|
@@ -47,8 +47,6 @@ public class OAuth2OpenController {
|
|
|
|
|
|
// POST oauth/check_token CheckTokenEndpoint
|
|
|
|
|
|
-// DELETE oauth/token ConsumerTokenServices#revokeToken
|
|
|
-
|
|
|
@Resource
|
|
|
private OAuth2GrantService oauth2GrantService;
|
|
|
@Resource
|
|
@@ -56,20 +54,38 @@ public class OAuth2OpenController {
|
|
|
@Resource
|
|
|
private OAuth2ApproveService oauth2ApproveService;
|
|
|
|
|
|
+ /**
|
|
|
+ * 对应 Spring Security OAuth 的 TokenEndpoint 类的 postAccessToken 方法
|
|
|
+ *
|
|
|
+ * 授权码 authorization_code 模式时:code + redirectUri + state 参数
|
|
|
+ * 密码 password 模式时:username + password + scope 参数
|
|
|
+ * 刷新 refresh_token 模式时:refreshToken 参数
|
|
|
+ * 客户端 client_credentials 模式:scope 参数
|
|
|
+ * 简化 implicit 模式时:不支持
|
|
|
+ *
|
|
|
+ * 注意,默认需要传递 client_id + client_secret 参数
|
|
|
+ */
|
|
|
@PostMapping("/token")
|
|
|
@ApiOperation(value = "获得访问令牌", notes = "适合 code 授权码模式,或者 implicit 简化模式;在 authorize.vue 单点登录界面被【获取】调用")
|
|
|
@ApiImplicitParams({
|
|
|
@ApiImplicitParam(name = "grant_type", required = true, value = "授权类型", example = "code", dataTypeClass = String.class),
|
|
|
@ApiImplicitParam(name = "code", value = "授权范围", example = "userinfo.read", dataTypeClass = String.class),
|
|
|
@ApiImplicitParam(name = "redirect_uri", value = "重定向 URI", example = "https://www.iocoder.cn", dataTypeClass = String.class),
|
|
|
- @ApiImplicitParam(name = "state", example = "123321", dataTypeClass = String.class)
|
|
|
+ @ApiImplicitParam(name = "username", example = "tudou", dataTypeClass = String.class),
|
|
|
+ @ApiImplicitParam(name = "password", example = "cai", dataTypeClass = String.class), // 多个使用空格分隔
|
|
|
+ @ApiImplicitParam(name = "scope", example = "user_info", dataTypeClass = String.class)
|
|
|
})
|
|
|
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
|
|
public CommonResult<OAuth2OpenAccessTokenRespVO> postAccessToken(HttpServletRequest request,
|
|
|
@RequestParam("grant_type") String grantType,
|
|
|
@RequestParam(value = "code", required = false) String code, // 授权码模式
|
|
|
@RequestParam(value = "redirect_uri", required = false) String redirectUri, // 授权码模式
|
|
|
- @RequestParam(value = "state", required = false) String state) { // 授权码模式
|
|
|
+ @RequestParam(value = "state", required = false) String state, // 授权码模式
|
|
|
+ @RequestParam(value = "username", required = false) String username, // 密码模式
|
|
|
+ @RequestParam(value = "password", required = false) String password, // 密码模式
|
|
|
+ @RequestParam(value = "scope", required = false) String scope, // 密码模式
|
|
|
+ @RequestParam(value = "refresh_token", required = false) String refreshToken) { // 刷新模式
|
|
|
+ List<String> scopes = OAuth2Utils.buildScopes(scope);
|
|
|
// 授权类型
|
|
|
OAuth2GrantTypeEnum grantTypeEnum = OAuth2GrantTypeEnum.getByGranType(grantType);
|
|
|
if (grantTypeEnum == null) {
|
|
@@ -80,23 +96,24 @@ public class OAuth2OpenController {
|
|
|
}
|
|
|
|
|
|
// 校验客户端
|
|
|
- String[] clientIdAndSecret = HttpUtils.obtainBasicAuthorization(request);
|
|
|
- if (ArrayUtil.isEmpty(clientIdAndSecret) || clientIdAndSecret.length != 2) {
|
|
|
- throw exception0(BAD_REQUEST.getCode(), "client_id 或 client_secret 未正确传递");
|
|
|
- }
|
|
|
- OAuth2ClientDO client = oauth2ClientService.validOAuthClientFromCache(clientIdAndSecret[0], clientIdAndSecret[1], grantType, null, null);
|
|
|
+ String[] clientIdAndSecret = obtainBasicAuthorization(request);
|
|
|
+ OAuth2ClientDO client = oauth2ClientService.validOAuthClientFromCache(clientIdAndSecret[0], clientIdAndSecret[1],
|
|
|
+ grantType, scopes, redirectUri);
|
|
|
|
|
|
// 根据授权模式,获取访问令牌
|
|
|
- OAuth2AccessTokenDO accessTokenDO = null;
|
|
|
+ OAuth2AccessTokenDO accessTokenDO;
|
|
|
switch (grantTypeEnum) {
|
|
|
case AUTHORIZATION_CODE:
|
|
|
accessTokenDO = oauth2GrantService.grantAuthorizationCodeForAccessToken(client.getClientId(), code, redirectUri, state);
|
|
|
break;
|
|
|
case PASSWORD:
|
|
|
+ accessTokenDO = oauth2GrantService.grantPassword(username, password, client.getClientId(), scopes);
|
|
|
break;
|
|
|
case CLIENT_CREDENTIALS:
|
|
|
+ accessTokenDO = oauth2GrantService.grantClientCredentials(client.getClientId(), scopes);
|
|
|
break;
|
|
|
case REFRESH_TOKEN:
|
|
|
+ accessTokenDO = oauth2GrantService.grantRefreshToken(refreshToken, client.getClientId());
|
|
|
break;
|
|
|
default:
|
|
|
throw new IllegalArgumentException("未知授权类型:" + grantType);
|
|
@@ -105,6 +122,24 @@ public class OAuth2OpenController {
|
|
|
return success(OAuth2OpenConvert.INSTANCE.convert(accessTokenDO));
|
|
|
}
|
|
|
|
|
|
+ @DeleteMapping("/token")
|
|
|
+ @ApiOperation(value = "删除访问令牌")
|
|
|
+ @ApiImplicitParam(name = "token", required = true, value = "访问令牌", example = "biu", dataTypeClass = String.class)
|
|
|
+ @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
|
|
+ public CommonResult<Boolean> revokeToken(HttpServletRequest request,
|
|
|
+ @RequestParam("token") String token) {
|
|
|
+ // 校验客户端
|
|
|
+ String[] clientIdAndSecret = obtainBasicAuthorization(request);
|
|
|
+ if (ArrayUtil.isEmpty(clientIdAndSecret) || clientIdAndSecret.length != 2) {
|
|
|
+ throw exception0(BAD_REQUEST.getCode(), "client_id 或 client_secret 未正确传递");
|
|
|
+ }
|
|
|
+ OAuth2ClientDO client = oauth2ClientService.validOAuthClientFromCache(clientIdAndSecret[0], clientIdAndSecret[1],
|
|
|
+ null, null, null);
|
|
|
+
|
|
|
+ // 删除访问令牌
|
|
|
+ return success(oauth2GrantService.revokeToken(client.getClientId(), token));
|
|
|
+ }
|
|
|
+
|
|
|
// GET oauth/authorize AuthorizationEndpoint TODO
|
|
|
@GetMapping("/authorize")
|
|
|
@ApiOperation(value = "获得授权信息", notes = "适合 code 授权码模式,或者 implicit 简化模式;在 authorize.vue 单点登录界面被【获取】调用")
|
|
@@ -229,4 +264,12 @@ public class OAuth2OpenController {
|
|
|
return UserTypeEnum.ADMIN.getValue();
|
|
|
}
|
|
|
|
|
|
+ private String[] obtainBasicAuthorization(HttpServletRequest request) {
|
|
|
+ String[] clientIdAndSecret = HttpUtils.obtainBasicAuthorization(request);
|
|
|
+ if (ArrayUtil.isEmpty(clientIdAndSecret) || clientIdAndSecret.length != 2) {
|
|
|
+ throw exception0(BAD_REQUEST.getCode(), "client_id 或 client_secret 未正确传递");
|
|
|
+ }
|
|
|
+ return clientIdAndSecret;
|
|
|
+ }
|
|
|
+
|
|
|
}
|