Commit a9928fa22713ee59385ebe59dc0298c7a6fb7ac1

Authored by YunaiV
1 parent c2937bd0

【功能优化】SYSTEM:支持通过 refreshToken 认证,解决部分场景不方便刷新访问令牌场景

yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java
@@ -13,7 +13,7 @@ import java.util.Set; @@ -13,7 +13,7 @@ import java.util.Set;
13 /** 13 /**
14 * 基于 MyBatis Plus 多租户的功能,实现 DB 层面的多租户的功能 14 * 基于 MyBatis Plus 多租户的功能,实现 DB 层面的多租户的功能
15 * 15 *
16 - * @author 16 + * @author 芋道源码
17 */ 17 */
18 public class TenantDatabaseInterceptor implements TenantLineHandler { 18 public class TenantDatabaseInterceptor implements TenantLineHandler {
19 19
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java
@@ -109,19 +109,18 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { @@ -109,19 +109,18 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
109 109
110 // 获取不到,从 MySQL 中获取访问令牌 110 // 获取不到,从 MySQL 中获取访问令牌
111 accessTokenDO = oauth2AccessTokenMapper.selectByAccessToken(accessToken); 111 accessTokenDO = oauth2AccessTokenMapper.selectByAccessToken(accessToken);
112 - if (accessTokenDO != null && DateUtils.isExpired(accessTokenDO.getExpiresTime())) {  
113 - accessTokenDO = null;  
114 - }  
115 - // 特殊:从 MySQL 中获取刷新令牌。原因:解决部分场景不方便刷新访问令牌场景  
116 - // 例如说,积木报表只允许传递 token,不允许传递 refresh_token,导致无法刷新访问令牌  
117 - // 再例如说,前端 WebSocket 的 token 直接跟在 url 上,无法传递 refresh_token  
118 - OAuth2RefreshTokenDO refreshTokenDO = oauth2RefreshTokenMapper.selectByRefreshToken(accessToken);  
119 - if (refreshTokenDO != null && !DateUtils.isExpired(refreshTokenDO.getExpiresTime())) {  
120 - accessTokenDO = convertToAccessToken(refreshTokenDO); 112 + if (accessTokenDO == null) {
  113 + // 特殊:从 MySQL 中获取刷新令牌。原因:解决部分场景不方便刷新访问令牌场景
  114 + // 例如说,积木报表只允许传递 token,不允许传递 refresh_token,导致无法刷新访问令牌
  115 + // 再例如说,前端 WebSocket 的 token 直接跟在 url 上,无法传递 refresh_token
  116 + OAuth2RefreshTokenDO refreshTokenDO = oauth2RefreshTokenMapper.selectByRefreshToken(accessToken);
  117 + if (refreshTokenDO != null && !DateUtils.isExpired(refreshTokenDO.getExpiresTime())) {
  118 + accessTokenDO = convertToAccessToken(refreshTokenDO);
  119 + }
121 } 120 }
122 121
123 // 如果在 MySQL 存在,则往 Redis 中写入 122 // 如果在 MySQL 存在,则往 Redis 中写入
124 - if (accessTokenDO != null) { 123 + if (accessTokenDO != null && !DateUtils.isExpired(accessTokenDO.getExpiresTime())) {
125 oauth2AccessTokenRedisDAO.set(accessTokenDO); 124 oauth2AccessTokenRedisDAO.set(accessTokenDO);
126 } 125 }
127 return accessTokenDO; 126 return accessTokenDO;
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImplTest.java
@@ -158,10 +158,11 @@ public class OAuth2TokenServiceImplTest extends BaseDbAndRedisUnitTest { @@ -158,10 +158,11 @@ public class OAuth2TokenServiceImplTest extends BaseDbAndRedisUnitTest {
158 .setAccessTokenValiditySeconds(30); 158 .setAccessTokenValiditySeconds(30);
159 when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO); 159 when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO);
160 // mock 数据(访问令牌) 160 // mock 数据(访问令牌)
161 - OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class)  
162 - .setRefreshToken(refreshToken).setClientId(clientId)  
163 - .setExpiresTime(LocalDateTime.now().plusDays(1))  
164 - .setUserType(UserTypeEnum.ADMIN.getValue()); 161 + OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class, o ->
  162 + o.setRefreshToken(refreshToken).setClientId(clientId)
  163 + .setExpiresTime(LocalDateTime.now().plusDays(1))
  164 + .setUserType(UserTypeEnum.ADMIN.getValue())
  165 + .setTenantId(TenantContextHolder.getTenantId()));
165 oauth2RefreshTokenMapper.insert(refreshTokenDO); 166 oauth2RefreshTokenMapper.insert(refreshTokenDO);
166 // mock 数据(访问令牌) 167 // mock 数据(访问令牌)
167 OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class).setRefreshToken(refreshToken) 168 OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class).setRefreshToken(refreshToken)
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql
@@ -473,7 +473,7 @@ CREATE TABLE IF NOT EXISTS "system_oauth2_access_token" ( @@ -473,7 +473,7 @@ CREATE TABLE IF NOT EXISTS "system_oauth2_access_token" (
473 "updater" varchar DEFAULT '', 473 "updater" varchar DEFAULT '',
474 "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 474 "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
475 "deleted" bit NOT NULL DEFAULT FALSE, 475 "deleted" bit NOT NULL DEFAULT FALSE,
476 - "tenant_id" bigint NOT NULL, 476 + "tenant_id" bigint not null,
477 PRIMARY KEY ("id") 477 PRIMARY KEY ("id")
478 ) COMMENT 'OAuth2 访问令牌'; 478 ) COMMENT 'OAuth2 访问令牌';
479 479
@@ -491,6 +491,7 @@ CREATE TABLE IF NOT EXISTS "system_oauth2_refresh_token" ( @@ -491,6 +491,7 @@ CREATE TABLE IF NOT EXISTS "system_oauth2_refresh_token" (
491 "updater" varchar DEFAULT '', 491 "updater" varchar DEFAULT '',
492 "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 492 "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
493 "deleted" bit NOT NULL DEFAULT FALSE, 493 "deleted" bit NOT NULL DEFAULT FALSE,
  494 + "tenant_id" bigint not null default '0',
494 PRIMARY KEY ("id") 495 PRIMARY KEY ("id")
495 ) COMMENT 'OAuth2 刷新令牌'; 496 ) COMMENT 'OAuth2 刷新令牌';
496 497