ThingsBoard 源码中的安全配置与 Security 模块

ThingsBoard 源码地址:https://github.com/thingsboard/thingsboard,启动成功之后,使用系统管理员: sysadmin@thingsboard.org / sysadmin 进行登陆。

设置和安全

登陆系统之后,点击左边的设置和安全菜单,进行相应的配置。

  1. 设置 -> 基本设置、发送邮件、通知

  2. 安全 -> 基本设置 -> 基本策略、密码策略、JWT 安全设置

  3. 安全 -> 双因素认证 -> 验证 APP、电子邮件、备份验证码、验证限制、验证码检查速率限制

  4. 安全 -> OAuth 2.0 -> 添加OAuth2.0客户端

    系统内置支持以下几种客户端。

​ 以 Google 为例,需要在 API 和服务 -> 凭据 -> OAuth 2.0 客户端 ID ,在 已获授权的重定向 URI 处添加 thingsboard 的重定向地址:http://localhost:8080/login/oauth2/code/

完成配置之后,配置的内存保证到数据库中,系统设置对应数据库表是 admin_settings

CREATE TABLE "public"."admin_settings" (
"id" uuid NOT NULL,
"tenant_id" uuid NOT NULL,
"created_time" int8 NOT NULL,
"json_value" varchar,
"key" varchar(255),
PRIMARY KEY ("id")
);

表中记录:

[
{
"id": "2fa02d60-b119-11ef-8167-dfb7a1b13a5a",
"tenant_id": "13814000-1dd2-11b2-8080-808080808080",
"created_time": 1733190720310,
"json_value": "{\"baseUrl\":\"http://localhost:8080\",\"prohibitDifferentUrl\":false}",
"key": "general"
},
{
"id": "2fa29e60-b119-11ef-8167-dfb7a1b13a5a",
"tenant_id": "13814000-1dd2-11b2-8080-808080808080",
"created_time": 1733190720326,
"json_value": "{\"coap\":{\"enabled\":true,\"host\":\"\",\"port\":\"5683\"},\"mqtt\":{\"enabled\":true,\"host\":\"\",\"port\":\"1883\"},\"http\":{\"enabled\":true,\"host\":\"\",\"port\":\"8080\"},\"mqtts\":{\"enabled\":false,\"host\":\"\",\"port\":\"8883\"},\"https\":{\"enabled\":false,\"host\":\"\",\"port\":\"443\"},\"coaps\":{\"enabled\":false,\"host\":\"\",\"port\":\"5684\"}}",
"key": "connectivity"
},
{
"id": "2fa18cf0-b119-11ef-8167-dfb7a1b13a5a",
"tenant_id": "13814000-1dd2-11b2-8080-808080808080",
"created_time": 1733190720319,
"json_value": "{\"mailFrom\":\"xxx\",\"smtpProtocol\":\"smtps\",\"smtpHost\":\"smtp.feishu.cn\",\"smtpPort\":\"465\",\"timeout\":\"10000\",\"enableTls\":false,\"username\":\"xxx\",\"tlsVersion\":null,\"enableProxy\":false,\"providerId\":\"CUSTOM\",\"proxyHost\":\"\",\"proxyPort\":null,\"proxyUser\":\"\",\"proxyPassword\":\"\",\"enableOauth2\":false,\"clientId\":\"\",\"clientSecret\":\"\",\"providerTenantId\":\"\",\"authUri\":\"\",\"tokenUri\":\"\",\"scope\":[],\"redirectUri\":\"\",\"password\":\"wQ7ae64vj2mXUBFZ\"}",
"key": "mail"
},
{
"id": "7c8790e0-b11a-11ef-983d-d79399efbf69",
"tenant_id": "13814000-1dd2-11b2-8080-808080808080",
"created_time": 1733191278830,
"json_value": "{\"passwordPolicy\":{\"minimumLength\":6,\"maximumLength\":72,\"minimumUppercaseLetters\":null,\"minimumLowercaseLetters\":null,\"minimumDigits\":null,\"minimumSpecialCharacters\":null,\"allowWhitespaces\":true,\"forceUserToResetPasswordIfNotValid\":false,\"passwordExpirationPeriodDays\":null,\"passwordReuseFrequencyDays\":null},\"maxFailedLoginAttempts\":5,\"userLockoutNotificationEmail\":null,\"mobileSecretKeyLength\":64,\"userActivationTokenTtl\":24,\"passwordResetTokenTtl\":24}",
"key": "securitySettings"
},
{
"id": "3d865ba0-b120-11ef-983d-d79399efbf69",
"tenant_id": "13814000-1dd2-11b2-8080-808080808080",
"created_time": 1733193750106,
"json_value": "{\"providers\":[{\"providerType\":\"TOTP\",\"issuerName\":\"ThingsBoard\"},{\"providerType\":\"EMAIL\",\"verificationCodeLifetime\":120},{\"providerType\":\"BACKUP_CODE\",\"codesQuantity\":10}],\"minVerificationCodeSendPeriod\":30,\"verificationCodeCheckRateLimit\":\"3:900\",\"maxVerificationFailuresBeforeUserLockout\":30,\"totalAllowedTimeForVerification\":3600}",
"key": "twoFaSettings"
},
{
"id": "2fa47320-b119-11ef-8167-dfb7a1b13a5a",
"tenant_id": "13814000-1dd2-11b2-8080-808080808080",
"created_time": 1733190720338,
"json_value": "{\"tokenExpirationTime\":9000,\"refreshTokenExpTime\":604800,\"tokenIssuer\":\"thingsboard.io\",\"tokenSigningKey\":\"anZjUDM5RXRHUEg2WHhNaEo0dE5pMzhiS0x2TURrMktCMkJYSDg0dUtPQ3k3ZzhnVW9yMHZpUjdUNzFYWWplOA==\"}",
"key": "jwt"
}
]

OAuth2 相关的表为:

账号

点击右上角三个竖点的账号按钮,进入个人账号设置页面,可以设置属性、安全和通知设置。

双因素认证可以使用以下身份验证:

个人账号的相关设置保存在以下两张表:

登陆页面

开启 OAuht2 之后,注销登陆,进入登陆页面。当前登陆页面会通过 http://localhost:8080/api/noauth/oauth2Clients?platform=WEB POST 接口(对应的 Controller 类为 OAuth2Controller)查询开通的 OAuth2 客户端列表。返回内容如下:

[
{
"name": "Google",
"icon": "google-logo",
"url": "/oauth2/authorization/f02246b0-b121-11ef-983d-d79399efbf69"
}
]

f02246b0-b121-11ef-983d-d79399efbf69 为 oauth2_client 主键。

在登陆页面,点击使用 Google 登陆,后台在 OAuth2AuthorizationRequestRedirectFilterdoFilterInternal 方法打个断点。

try {
OAuth2AuthorizationRequest authorizationRequest = this.authorizationRequestResolver.resolve(request);
if (authorizationRequest != null) {
this.sendRedirectForAuthorization(request, response, authorizationRequest);
return;
}
}
catch (Exception ex) {
this.unsuccessfulRedirectForAuthorization(request, response, ex);
return;
}

this.authorizationRequestResolver 对于的 Bean 为 CustomOAuth2AuthorizationRequestResolver,其 resolve 方法逻辑如下:

@Override
public OAuth2AuthorizationRequest resolve(HttpServletRequest request) {
String registrationId = this.resolveRegistrationId(request);
String redirectUriAction = getAction(request, "login");
String appPackage = getAppPackage(request);
String platform = getPlatform(request);
String appToken = getAppToken(request);
return resolve(request, registrationId, redirectUriAction, appPackage, platform, appToken);
}

OAuth2 Client 配置

OAuth2 Client 相关配置在 ThingsboardSecurityConfiguration

@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
/...
if (oauth2Configuration != null) {
http.oauth2Login(login -> login
.authorizationEndpoint(config -> config
.authorizationRequestRepository(httpCookieOAuth2AuthorizationRequestRepository)
.authorizationRequestResolver(oAuth2AuthorizationRequestResolver))
.loginPage("/oauth2Login")
.loginProcessingUrl(oauth2Configuration.getLoginProcessingUrl())
.successHandler(oauth2AuthenticationSuccessHandler)
.failureHandler(oauth2AuthenticationFailureHandler));
}
return http.build();
}

oauth2Login 的 authorizationEndpoint 配置了一个 authorizationRequestRepositoryauthorizationRequestResolver

authorizationRequestRepository 对应的是 HttpCookieOAuth2AuthorizationRequestRepository,保存 request 请求地址到 cookie;authorizationRequestResolver 对应的是 CustomOAuth2AuthorizationRequestResolver

oauth2Login 的登陆页面为 /oauth2Login,处理登陆请求的地址为 oauth2Configuration.getLoginProcessingUrl(),oauth2Configuration 的配置:

security:
oauth2:
# Redirect URL where access code from external user management system will be processed
loginProcessingUrl: "${SECURITY_OAUTH2_LOGIN_PROCESSING_URL://login/oauth2/code/}"
githubMapper:
# The email addresses that will be mapped from the URL
emailUrl: "${SECURITY_OAUTH2_GITHUB_MAPPER_EMAIL_URL_KEY:https://api.github.com/user/emails}"

oauth2Login 登陆成功的 handler 为 Oauth2AuthenticationSuccessHandler

oauth2Login 登陆失败的 handler 为 Oauth2AuthenticationFailureHandler

所以,OAuth2 client 相关代码重点在以下类:

订阅文章

订阅更新,不错过后续文章

直接通过 RSS 和 Telegram 订阅本站更新。

订阅 RSS关注 Telegram

分享文章

如果这篇有帮助,可以顺手转发

直接分享给同事、朋友,或者发到你的社交平台。

分享到 X 分享到 Telegram 邮件分享
限流是什么:原理、目的与常见方案
ThingsBoard 源码中的 GitHub Actions