:::info
匹配版本:V3.20
页面状态:已完成
原文地址:点击跳转
:::
概述
ThingsBoard允许您为客户提供单点登录功能,并使用支持OAuth 2.0协议的外部用户管理平台自动创建租户,客户或子客户。
支持OAuth 2.0协议的平台列表:Google,Okta,Auth0等。
OAuth 2.0身份验证流程
ThingsBoard支持授权码授予类型,以交换访问令牌的授权码。
用户通过重定向URL返回ThingsBoard客户端后,平台将从URL获取授权代码,并将其用于从外部用户管理平台请求访问令牌。使用基本映射器或自定义映射器,外部用户信息对象将从外部平台转换为ThingsBoard内部OAuth 2.0用户。此后,将发生常规的ThingsBoard授权流程。
场景描述
在此示例中,我们将使用Google身份验证。用户将登录到租户,并且租户名称将等于用户的电子邮件。如果系统中不存在租户,则将创建新的租户。
第二步,我们将添加新的身份验证外部提供者Auth0。在这种情况下,用户将登录到租户,该租户的名称将等于用户电子邮件域名。此外,对于每个用户,我们将创建一个新的客户,并且客户名称将等于用户电子邮件。
要从Google和Auth0平台映射该外部用户信息,我们将使用内置的基本mapper。
如果基本的映射器功能不适合您的业务需求,则可以配置自定义映射器,以便您可以添加满足特定需求的实现。
用谷歌登录
要将Google OAuth 2.0身份验证平台用于登录,您需要在Google API控制台中设置一个项目以获得OAuth 2.0凭据。
请按照OpenID Connect页面上的说明配置OAuth 2.0客户端。完成上述说明后,您应该拥有一个新的OAuth客户端,其凭据由客户端ID和客户端密钥组成。
请在我们的示例中将ThingsBoard默认重定向URI添加到“授权重定向URI”部分中:
http://localhost:8080/login/oauth2/code/
ThingsBoard的配置
以系统管理员身份进入ThingsBoard(sysadmin@thingsboard.org / sysadmin)。然后在“主页”部分中找到“ OAuth2”图标,然后单击它。
检查启用OAuth2设置,然后点击+添加。在出现的窗口中单击localhost,以进行进一步的设置。
选择所需的协议。如果决定使用HTTP协议,请确保在域名(localhost:8080)中记下其端口8080。在此示例中,我们将配置Google提供程序。单击此块。
请从您的Google API控制台中提供信息(客户端ID和客户端密钥)。然后展开“自定义设置”菜单。
让我们为General块进行设置。使用此链接可以查看最新URL列表,例如accessTokenUri,authorizationUri等。在“客户端身份验证方法”字段中选择POST。然后选中“允许用户创建”复选框。添加到范围字段:openid,电子邮件,个人资料。并转到Mapper块。
选择基本类型,并在必要时填写字段(下面在“基本映射器”部分中将在本文中进行详细描述)。某些配置仅在Professional Edition中可用。然后,保存设置。
这样,为Google生成的oauth2配置将类似于下面提供的配置。
如果导航到“登录”屏幕,我们将看到Google的另一个“登录”选项:
单击它并选择一个Google帐户后,我们将使用Google的电子邮件作为Tenant Administrator电子邮件登录到ThingsBoard:
根据基本的映射器,如果您以系统管理员身份登录,您将看到租户名称是我们Google的电子邮件:
使用Auth0登录
现在,让我们向列表中添加一个提供者Auth0。这次,我们将在一个域租户中为我们的用户创建客户。
要使用Auth0身份验证平台进行登录,请在此链接之后创建一个“常规Web应用”类型的新应用。
从技术列表中,选择Java Spring Boot:
创建应用程序后,您可以导航到应用程序详细信息以获得clientId和clientSecret:
同时,请更新您允许的回调URL:
http://localhost:8080/login/oauth2/code/
请注意,没有必要更新应用程序登录URI。
在高级详细信息部分中,您将能够找到OAuth 2.0配置所需的所有URL(端点):
ThingsBoard的配置
现在,我们可以再添加一个提供程序:
然后选择自定义:
请从您的应用程序详细信息中提供信息(客户端ID和客户端密钥),然后您可以在高级详细信息部分中找到所有必需的URL。
在客户端身份验证方法字段中选择POST。我们在提供者标签字段中指示Auth0。然后选中“允许用户创建”复选框。添加到范围字段:openid,电子邮件,个人资料。并转到Mapper块。
选择“基本”类型,并在必要时填写字段(本文下面“基本”映射器部分中对此进行了详细描述)。某些配置仅在Professional Edition中可用。然后,保存设置。
这样,为OAuth0生成的oauth2配置将类似于下面提供的配置。
如果我们导航到登录页面,我们将看到的选项两种可能的登录-谷歌和Auth0:
单击它并选择我们的Auth0帐户后,我们将以客户用户的电子邮件身份登录ThingsBoard:
如果我们以系统管理员身份登录,则根据基本映射器,您将看到租户名称是我们的Auth0电子邮件域名:
我们已经完成了示例,现在不需要您的用户在ThingsBoard中创建帐户-他们可以为此使用已经存在的SSO提供程序。
结果被剪断
将外部用户映射到ThingBoard内部用户结构
可以通过两种方式将外部用户信息对象映射到ThingBoard用户中-使用基本和自定义映射器。映射器的主要功能是将键值属性从外部用户信息对象映射到ThingsBoard OAuth 2.0用户的预期结构中:
public class OAuth2User {
private String tenantName;
private TenantId tenantId;
private String customerName;
private CustomerId customerId;
private String email;
private String firstName;
private String lastName;
private boolean alwaysFullScreen;
private String defaultDashboardName;
// NOTE: Next configurations available only in Professional Edition
private List<String> userGroups;
private String parentCustomerName;
private CustomerId parentCustomerId;
}
基本映射器
基本的映射器能够使用一组预定义的规则将外部OAuth 2.0用户信息对象合并到ThingsBoard OAuth 2.0用户中。
要使用基本的映射器,请将mapperConfig.type或SECURITY_OAUTH2_DEFAULT_MAPPER_TYPE环境变量设置为basic。
以下是其他属性的详细信息:
- allowUserCreation-如果此选项设置为true,则万一东西在ThingsBoard中不存在,将被创建。如果此选项设置为false,则用户将遇到拒绝访问错误,以防万一他尝试使用外部OAuth 2.0提供程序登录,但ThingsBoard上没有使用这些凭据的用户。
- emailAttributeKey-这是来自外部OAuth 2.0用户信息的属性的键,该信息将用作ThingsBoard用户电子邮件属性。
- firstNameAttributeKey-这是来自外部OAuth 2.0用户信息的属性的键,该信息将用作ThingsBoard用户的名字属性。
- lastNameAttributeKey-这是来自外部OAuth 2.0用户信息的属性的键,该信息将用作ThingsBoard用户姓氏属性。
- tenantNameStrategy-此选项指定要选择哪个租户来创建用户。基本的映射器提供了三种可能的选项策略,用于从外部用户信息对象域,电子邮件或自定义生成租户名称:
- 域-租户的名称将从用户的电子邮件中提取为域;
- 电子邮件-租户的名称将是用户的电子邮件;
- custom-可以为租户名称设置自定义模式。请参阅tenantNamePattern。
- tenantNamePattern-万一tenantNameStrategy是自定义的,您可以指定租户的名称,在该位置将借助自定义模式在其中创建用户。您可以使用外部用户信息对象中的属性将其放入租户的名称。请使用%{attribute_key}作为属性值的占位符。租户模式示例:
- 演示租户 #硬编码的租户名称;
- 演示租户%{email} #如果用户的电子邮件为test@demo.com,则租户的名称将为“ Demo租户test@demo.com ”;
- %{givenName} #如果用户的namedName属性为Demo User,则租户名称将为‘Demo User’。
- customerNamePattern用户可以在特定客户下创建,如果此模式字段不为空,则不能在租户下创建。您可以使用外部用户信息对象中的属性将其放入“客户”名称中。请使用%{attribute_key}作为属性值的占位符。客户模式示例:
- 演示客户 编号硬编码的客户名称;
- 演示客户%{email} #如果用户的电子邮件属性为test@demo.com,则客户名称为‘Demo Customer test@demo.com ‘ ;
- %{city} #如果用户的城市属性是New York,则客户名称将是‘New York’。
- defaultDashboardName 如果此字段不为空,则用户将被重定向到特定的Dashboard。
- alwaysFullScreen 如果此字段为true并且defaultDashboardName不为空,则将以全屏模式将用户重定向到特定的Dashboard。
- parentCustomerNamePattern注意:此配置仅在Professional Edition中可用。如果此模式字段不为空,则可以在此父客户下的层次结构中创建用户的客户。您可以使用外部用户信息对象中的属性将其放入“父客户”名称中。请使用%{attribute_key}作为属性值的占位符。父客户模式示例:
- 演示父客户 编号硬编码的父客户名称;
- 演示父客户%{email} #如果用户的电子邮件属性为test@demo.com,则父客户名称将为‘Demo父客户test@demo.com ‘ ;
- %{country} #如果用户的国家/地区属性为“主要客户”,则“父客户”名称将为““父客户””。
userGroupsNamePattern注意:此配置仅在Professional Edition中可用。默认情况下,新创建的用户仅分配给所有用户的组。您可以通过指定组列表来自定义此行为,在组列表中也必须分配用户。您可以使用外部用户信息对象中的属性将其放入用户组名称中。请使用%{attribute_key}作为属性值的占位符。如果组不存在,将自动创建该组。用户组模式示例:
- 租户管理员,管理员 #硬编码的用户组;
%{job_title} #如果用户的job_title属性为Manager,则将用户分配到Manager用户组中。
自定义映射器
如果基本的映射器功能不能满足您的业务需求,则可以在自定义映射器的帮助下添加适合您特定目标的实现。
一个定制的映射器,被设计为在ThingsBoard核心微服务附近运行的独立微服务。ThingsBoard将所有映射请求转发到此微服务,并希望作为响应的ThingsBoard OAuth 2.0用户对象:public class OAuth2User {
private String tenantName;
private TenantId tenantId;
private String customerName;
private CustomerId customerId;
private String email;
private String firstName;
private String lastName;
private boolean alwaysFullScreen;
private String defaultDashboardName;
// NOTE: Next configurations available only in Professional Edition
private List<String> userGroups;
private String parentCustomerName;
private CustomerId parentCustomerId;
}
请将此基本实现作为自定义映射器的起点。
要使用自定义映射器,请将mapperConfig.type或SECURITY_OAUTH2_DEFAULT_MAPPER_TYPE环境变量设置为custom。
以下是其他属性的详细信息:
网址
自定义映射器端点的URL。- 用户名
如果自定义映射器端点配置了基本授权,请在此属性中指定用户名。 - 密码
如果自定义映射器端点配置了基本授权,请在此属性中指定密码。
这是演示配置的示例:
custom:
url: http://localhost:10010/oauth2/mapper
username: admin
password: pa$$word
OAuth 2.0配置参数
键 | 描述 |
---|---|
security.oauth2.enabled | 启用/禁用OAuth 2.0登录功能 |
security.oauth2.loginProcessingUrl | 重定向URL,将在该URL中处理来自外部用户管理系统的访问代码 |
security.oauth2.clients.default.loginButtonLabel | 标记要在登录按钮上显示的标签-“使用{loginButtonLabel}登录” |
security.oauth2.clients.default.loginButtonIcon | 将在登录按钮上显示的图标。材料设计图标ID。可以在此处找到图标ID列表 |
security.oauth2.clients.default.clientName | 客户或注册的逻辑名称 |
security.oauth2.clients.default.clientId | 客户编号 |
security.oauth2.clients.default.clientSecret | 客户机密 |
security.oauth2.clients.default.accessTokenUri | 令牌端点的URI |
security.oauth2.clients.default.authorizationUri | 授权端点的URI |
security.oauth2.clients.default.scope | 设置客户端使用的范围 |
security.oauth2.clients.default.redirectUriTemplate | 重定向端点的URI(或uri模板)。必须与“ security.oauth2.loginProcessingUrl”(添加域名)同步 |
security.oauth2.clients.default.jwkSetUri | JSON Web密钥(JWK)设置端点的URI |
security.oauth2.clients.default.authorizationGrantType | 用于客户端的授权授予类型 |
security.oauth2.clients.default.clientAuthenticationMethod | 使用授权服务器对客户端进行身份验证时使用的身份验证方法 |
security.oauth2.clients.default.userInfoUri | 用户信息端点的URI |
security.oauth2.clients.default.userNameAttributeName | 用于从用户信息响应中访问用户名的属性名 |
HaProxy配置
如果ThingsBoard在类似HAProxy的负载平衡器下运行,请正确配置平衡算法,以确保在ThingsBoard实例上可以使用正确的会话:
backend tb-api-backend
...
balance source # balance must be set to 'source'
...
同样,请为HTTP和HTTPs请求正确配置ACL映射:
frontend http-in
...
acl tb_api_acl path_beg /api/ /swagger /webjars /v2/ /static/rulenode/ /oauth2/ /login/oauth2/ # '/oauth2/ /login/oauth2/' added
...
frontend https_in
...
acl tb_api_acl path_beg /api/ /swagger /webjars /v2/ /static/rulenode/ /oauth2/ /login/oauth2/ # '/oauth2/ /login/oauth2/' added
...