:::info 匹配版本:V3.20
页面状态:已完成
原文地址:点击跳转 :::

概述

ThingsBoard允许您为客户提供单点登录功能,并使用支持OAuth 2.0协议的外部用户管理平台自动创建租户,客户或子客户。
支持OAuth 2.0协议的平台列表:GoogleOktaAuth0等。

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和客户端密钥组成。
支持 OAuth 2.0 - 图1
支持 OAuth 2.0 - 图2
支持 OAuth 2.0 - 图3
请在我们的示例中将ThingsBoard默认重定向URI添加到“授权重定向URI”部分中:

  1. http://localhost:8080/login/oauth2/code/

支持 OAuth 2.0 - 图4

ThingsBoard的配置

以系统管理员身份进入ThingsBoard(sysadmin@thingsboard.org / sysadmin)。然后在“主页”部分中找到“ OAuth2”图标,然后单击它。
支持 OAuth 2.0 - 图5
检查启用OAuth2设置,然后点击+添加。在出现的窗口中单击localhost,以进行进一步的设置。
支持 OAuth 2.0 - 图6
选择所需的协议。如果决定使用HTTP协议,请确保在域名(localhost:8080)中记下其端口8080。在此示例中,我们将配置Google提供程序。单击此块。
支持 OAuth 2.0 - 图7
请从您的Google API控制台中提供信息(客户端ID客户端密钥)。然后展开“自定义设置”菜单。
支持 OAuth 2.0 - 图8
让我们为General块进行设置。使用此链接可以查看最新URL列表,例如accessTokenUriauthorizationUri等。在“客户端身份验证方法”字段中选择POST。然后选中“允许用户创建”复选框。添加到范围字段:openid,电子邮件,个人资料。并转到Mapper块。
支持 OAuth 2.0 - 图9
选择基本类型,并在必要时填写字段(下面在“基本映射器”部分中将在本文中进行详细描述)。某些配置仅在Professional Edition中可用。然后,保存设置
支持 OAuth 2.0 - 图10
这样,为Google生成的oauth2配置将类似于下面提供的配置。
如果导航到“登录”屏幕,我们将看到Google的另一个“登录”选项:
支持 OAuth 2.0 - 图11
单击它并选择一个Google帐户后,我们将使用Google的电子邮件作为Tenant Administrator电子邮件登录到ThingsBoard:
支持 OAuth 2.0 - 图12
根据基本的映射器,如果您以系统管理员身份登录,您将看到租户名称是我们Google的电子邮件:
支持 OAuth 2.0 - 图13

使用Auth0登录

现在,让我们向列表中添加一个提供者Auth0。这次,我们将在一个域租户中为我们的用户创建客户。
要使用Auth0身份验证平台进行登录,请在此链接之后创建一个“常规Web应用”类型的新应用。
支持 OAuth 2.0 - 图14
从技术列表中,选择Java Spring Boot
支持 OAuth 2.0 - 图15
创建应用程序后,您可以导航到应用程序详细信息以获得clientIdclientSecret
支持 OAuth 2.0 - 图16
同时,请更新您允许的回调URL:

  1. http://localhost:8080/login/oauth2/code/

请注意,没有必要更新应用程序登录URI。
支持 OAuth 2.0 - 图17
在高级详细信息部分中,您将能够找到OAuth 2.0配置所需的所有URL(端点):
支持 OAuth 2.0 - 图18

ThingsBoard的配置

现在,我们可以再添加一个提供程序:
支持 OAuth 2.0 - 图19
然后选择自定义:
支持 OAuth 2.0 - 图20
请从您的应用程序详细信息中提供信息(客户端ID客户端密钥),然后您可以在高级详细信息部分中找到所有必需的URL。
客户端身份验证方法字段中选择POST。我们在提供者标签字段中指示Auth0。然后选中“允许用户创建”复选框。添加到范围字段:openid,电子邮件,个人资料。并转到Mapper块。
支持 OAuth 2.0 - 图21
选择“基本”类型,并在必要时填写字段(本文下面“基本”映射器部分中对此进行了详细描述)。某些配置仅在Professional Edition中可用。然后,保存设置。
支持 OAuth 2.0 - 图22
这样,为OAuth0生成的oauth2配置将类似于下面提供的配置。
如果我们导航到登录页面,我们将看到的选项两种可能的登录-谷歌Auth0
支持 OAuth 2.0 - 图23
单击它并选择我们的Auth0帐户后,我们将以客户用户的电子邮件身份登录ThingsBoard:
支持 OAuth 2.0 - 图24
如果我们以系统管理员身份登录,则根据基本映射器,您将看到租户名称是我们的Auth0电子邮件域名:
支持 OAuth 2.0 - 图25
我们已经完成了示例,现在不需要您的用户在ThingsBoard中创建帐户-他们可以为此使用已经存在的SSO提供程序。

结果被剪断

此代码片段包含在我们的示例中使用的两个提供程序:
支持 OAuth 2.0 - 图26

将外部用户映射到ThingBoard内部用户结构

可以通过两种方式将外部用户信息对象映射到ThingBoard用户中-使用基本自定义映射器。映射器的主要功能是将键值属性从外部用户信息对象映射到ThingsBoard OAuth 2.0用户的预期结构中:

  1. public class OAuth2User {
  2. private String tenantName;
  3. private TenantId tenantId;
  4. private String customerName;
  5. private CustomerId customerId;
  6. private String email;
  7. private String firstName;
  8. private String lastName;
  9. private boolean alwaysFullScreen;
  10. private String defaultDashboardName;
  11. // NOTE: Next configurations available only in Professional Edition
  12. private List<String> userGroups;
  13. private String parentCustomerName;
  14. private CustomerId parentCustomerId;
  15. }

基本映射器

基本的映射器能够使用一组预定义的规则将外部OAuth 2.0用户信息对象合并到ThingsBoard OAuth 2.0用户中。
支持 OAuth 2.0 - 图27
要使用基本的映射器,请将mapperConfig.typeSECURITY_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用户对象:

      1. public class OAuth2User {
      2. private String tenantName;
      3. private TenantId tenantId;
      4. private String customerName;
      5. private CustomerId customerId;
      6. private String email;
      7. private String firstName;
      8. private String lastName;
      9. private boolean alwaysFullScreen;
      10. private String defaultDashboardName;
      11. // NOTE: Next configurations available only in Professional Edition
      12. private List<String> userGroups;
      13. private String parentCustomerName;
      14. private CustomerId parentCustomerId;
      15. }

      请将此基本实现作为自定义映射器的起点。
      要使用自定义映射器,请将mapperConfig.typeSECURITY_OAUTH2_DEFAULT_MAPPER_TYPE环境变量设置为custom
      以下是其他属性的详细信息:

  • 网址
    自定义映射器端点的URL。

  • 用户名
    如果自定义映射器端点配置了基本授权,请在此属性中指定用户名
  • 密码
    如果自定义映射器端点配置了基本授权,请在此属性中指定密码

这是演示配置的示例:

  1. custom:
  2. url: http://localhost:10010/oauth2/mapper
  3. username: admin
  4. password: pa$$word

支持 OAuth 2.0 - 图28

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实例上可以使用正确的会话:

  1. backend tb-api-backend
  2. ...
  3. balance source # balance must be set to 'source'
  4. ...

同样,请为HTTP和HTTPs请求正确配置ACL映射:

  1. frontend http-in
  2. ...
  3. acl tb_api_acl path_beg /api/ /swagger /webjars /v2/ /static/rulenode/ /oauth2/ /login/oauth2/ # '/oauth2/ /login/oauth2/' added
  4. ...
  1. frontend https_in
  2. ...
  3. acl tb_api_acl path_beg /api/ /swagger /webjars /v2/ /static/rulenode/ /oauth2/ /login/oauth2/ # '/oauth2/ /login/oauth2/' added
  4. ...

下一步

用谷歌登录