Commit 98ed8009455f3e3f548a3c063a672f91e68817c9
1 parent
e8383407
feat:【system 系统管理】oauth2 支持 ClientCredentials 模式
Showing
4 changed files
with
32 additions
and
12 deletions
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.http
| @@ -35,6 +35,14 @@ tenant-id: {{adminTenantId}} | @@ -35,6 +35,14 @@ tenant-id: {{adminTenantId}} | ||
| 35 | 35 | ||
| 36 | grant_type=password&username=admin&password=admin123&scope=user.read | 36 | grant_type=password&username=admin&password=admin123&scope=user.read |
| 37 | 37 | ||
| 38 | +### 请求 /system/oauth2/token + client_credentials 接口 => 成功 | ||
| 39 | +POST {{baseUrl}}/system/oauth2/token | ||
| 40 | +Content-Type: application/x-www-form-urlencoded | ||
| 41 | +Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw== | ||
| 42 | +tenant-id: {{adminTenantId}} | ||
| 43 | + | ||
| 44 | +grant_type=client_credentials&scope=user.read | ||
| 45 | + | ||
| 38 | ### 请求 /system/oauth2/token + refresh_token 接口 => 成功 | 46 | ### 请求 /system/oauth2/token + refresh_token 接口 => 成功 |
| 39 | POST {{baseUrl}}/system/oauth2/token | 47 | POST {{baseUrl}}/system/oauth2/token |
| 40 | Content-Type: application/x-www-form-urlencoded | 48 | Content-Type: application/x-www-form-urlencoded |
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java
| @@ -94,6 +94,7 @@ public class OAuth2OpenController { | @@ -94,6 +94,7 @@ public class OAuth2OpenController { | ||
| 94 | @Parameter(name = "scope", example = "user_info"), | 94 | @Parameter(name = "scope", example = "user_info"), |
| 95 | @Parameter(name = "refresh_token", example = "123424233"), | 95 | @Parameter(name = "refresh_token", example = "123424233"), |
| 96 | }) | 96 | }) |
| 97 | + @SuppressWarnings("EnhancedSwitchMigration") | ||
| 97 | public CommonResult<OAuth2OpenAccessTokenRespVO> postAccessToken(HttpServletRequest request, | 98 | public CommonResult<OAuth2OpenAccessTokenRespVO> postAccessToken(HttpServletRequest request, |
| 98 | @RequestParam("grant_type") String grantType, | 99 | @RequestParam("grant_type") String grantType, |
| 99 | @RequestParam(value = "code", required = false) String code, // 授权码模式 | 100 | @RequestParam(value = "code", required = false) String code, // 授权码模式 |
| @@ -119,15 +120,23 @@ public class OAuth2OpenController { | @@ -119,15 +120,23 @@ public class OAuth2OpenController { | ||
| 119 | grantType, scopes, redirectUri); | 120 | grantType, scopes, redirectUri); |
| 120 | 121 | ||
| 121 | // 2. 根据授权模式,获取访问令牌 | 122 | // 2. 根据授权模式,获取访问令牌 |
| 122 | - OAuth2AccessTokenDO accessTokenDO = switch (grantTypeEnum) { | ||
| 123 | - // TODO @xingyu:这里改了,可能会影响 jdk8 版本哈; | ||
| 124 | - case AUTHORIZATION_CODE -> | ||
| 125 | - oauth2GrantService.grantAuthorizationCodeForAccessToken(client.getClientId(), code, redirectUri, state); | ||
| 126 | - case PASSWORD -> oauth2GrantService.grantPassword(username, password, client.getClientId(), scopes); | ||
| 127 | - case CLIENT_CREDENTIALS -> oauth2GrantService.grantClientCredentials(client.getClientId(), scopes); | ||
| 128 | - case REFRESH_TOKEN -> oauth2GrantService.grantRefreshToken(refreshToken, client.getClientId()); | ||
| 129 | - default -> throw new IllegalArgumentException("未知授权类型:" + grantType); | ||
| 130 | - }; | 123 | + OAuth2AccessTokenDO accessTokenDO; |
| 124 | + switch (grantTypeEnum) { | ||
| 125 | + case AUTHORIZATION_CODE: | ||
| 126 | + accessTokenDO = oauth2GrantService.grantAuthorizationCodeForAccessToken(client.getClientId(), code, redirectUri, state); | ||
| 127 | + break; | ||
| 128 | + case PASSWORD: | ||
| 129 | + accessTokenDO = oauth2GrantService.grantPassword(username, password, client.getClientId(), scopes); | ||
| 130 | + break; | ||
| 131 | + case CLIENT_CREDENTIALS: | ||
| 132 | + accessTokenDO = oauth2GrantService.grantClientCredentials(client.getClientId(), scopes); | ||
| 133 | + break; | ||
| 134 | + case REFRESH_TOKEN: | ||
| 135 | + accessTokenDO = oauth2GrantService.grantRefreshToken(refreshToken, client.getClientId()); | ||
| 136 | + break; | ||
| 137 | + default: | ||
| 138 | + throw new IllegalArgumentException("未知授权类型:" + grantType); | ||
| 139 | + } | ||
| 131 | Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查 | 140 | Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查 |
| 132 | return success(OAuth2OpenConvert.INSTANCE.convert(accessTokenDO)); | 141 | return success(OAuth2OpenConvert.INSTANCE.convert(accessTokenDO)); |
| 133 | } | 142 | } |
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2GrantServiceImpl.java
| @@ -86,8 +86,8 @@ public class OAuth2GrantServiceImpl implements OAuth2GrantService { | @@ -86,8 +86,8 @@ public class OAuth2GrantServiceImpl implements OAuth2GrantService { | ||
| 86 | 86 | ||
| 87 | @Override | 87 | @Override |
| 88 | public OAuth2AccessTokenDO grantClientCredentials(String clientId, List<String> scopes) { | 88 | public OAuth2AccessTokenDO grantClientCredentials(String clientId, List<String> scopes) { |
| 89 | - // TODO 芋艿:项目中使用 OAuth2 解决的是三方应用的授权,内部的 SSO 等问题,所以暂时不考虑 client_credentials 这个场景 | ||
| 90 | - throw new UnsupportedOperationException("暂时不支持 client_credentials 授权模式"); | 89 | + // 特殊:https://yuanbao.tencent.com/bot/app/share/chat/wFj642xSZHHx |
| 90 | + return oauth2TokenService.createAccessToken(0L, UserTypeEnum.ADMIN.getValue(), clientId, scopes); | ||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | @Override | 93 | @Override |
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java
| @@ -197,6 +197,9 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { | @@ -197,6 +197,9 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { | ||
| 197 | * @return 用户信息 | 197 | * @return 用户信息 |
| 198 | */ | 198 | */ |
| 199 | private Map<String, String> buildUserInfo(Long userId, Integer userType) { | 199 | private Map<String, String> buildUserInfo(Long userId, Integer userType) { |
| 200 | + if (userId == null || userId <= 0) { | ||
| 201 | + return Collections.emptyMap(); | ||
| 202 | + } | ||
| 200 | if (userType.equals(UserTypeEnum.ADMIN.getValue())) { | 203 | if (userType.equals(UserTypeEnum.ADMIN.getValue())) { |
| 201 | AdminUserDO user = adminUserService.getUser(userId); | 204 | AdminUserDO user = adminUserService.getUser(userId); |
| 202 | return MapUtil.builder(LoginUser.INFO_KEY_NICKNAME, user.getNickname()) | 205 | return MapUtil.builder(LoginUser.INFO_KEY_NICKNAME, user.getNickname()) |
| @@ -205,7 +208,7 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { | @@ -205,7 +208,7 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { | ||
| 205 | // 注意:目前 Member 暂时不读取,可以按需实现 | 208 | // 注意:目前 Member 暂时不读取,可以按需实现 |
| 206 | return Collections.emptyMap(); | 209 | return Collections.emptyMap(); |
| 207 | } | 210 | } |
| 208 | - return null; | 211 | + throw new IllegalArgumentException("未知用户类型:" + userType); |
| 209 | } | 212 | } |
| 210 | 213 | ||
| 211 | private static String generateAccessToken() { | 214 | private static String generateAccessToken() { |