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 | 35 | |
| 36 | 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 | 46 | ### 请求 /system/oauth2/token + refresh_token 接口 => 成功 |
| 39 | 47 | POST {{baseUrl}}/system/oauth2/token |
| 40 | 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 | 94 | @Parameter(name = "scope", example = "user_info"), |
| 95 | 95 | @Parameter(name = "refresh_token", example = "123424233"), |
| 96 | 96 | }) |
| 97 | + @SuppressWarnings("EnhancedSwitchMigration") | |
| 97 | 98 | public CommonResult<OAuth2OpenAccessTokenRespVO> postAccessToken(HttpServletRequest request, |
| 98 | 99 | @RequestParam("grant_type") String grantType, |
| 99 | 100 | @RequestParam(value = "code", required = false) String code, // 授权码模式 |
| ... | ... | @@ -119,15 +120,23 @@ public class OAuth2OpenController { |
| 119 | 120 | grantType, scopes, redirectUri); |
| 120 | 121 | |
| 121 | 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 | 140 | Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查 |
| 132 | 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 | 86 | |
| 87 | 87 | @Override |
| 88 | 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 | 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 | 197 | * @return 用户信息 |
| 198 | 198 | */ |
| 199 | 199 | private Map<String, String> buildUserInfo(Long userId, Integer userType) { |
| 200 | + if (userId == null || userId <= 0) { | |
| 201 | + return Collections.emptyMap(); | |
| 202 | + } | |
| 200 | 203 | if (userType.equals(UserTypeEnum.ADMIN.getValue())) { |
| 201 | 204 | AdminUserDO user = adminUserService.getUser(userId); |
| 202 | 205 | return MapUtil.builder(LoginUser.INFO_KEY_NICKNAME, user.getNickname()) |
| ... | ... | @@ -205,7 +208,7 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { |
| 205 | 208 | // 注意:目前 Member 暂时不读取,可以按需实现 |
| 206 | 209 | return Collections.emptyMap(); |
| 207 | 210 | } |
| 208 | - return null; | |
| 211 | + throw new IllegalArgumentException("未知用户类型:" + userType); | |
| 209 | 212 | } |
| 210 | 213 | |
| 211 | 214 | private static String generateAccessToken() { | ... | ... |