mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 18:28:43 +08:00 
			
		
		
		
	完成 oauth2 check-token 校验 token 的实现
This commit is contained in:
		| @@ -42,3 +42,8 @@ grant_type=refresh_token&refresh_token=00895465d6994f72a9d926ceeed0f588 | |||||||
| DELETE {{baseUrl}}/system/oauth2/token?token=ca8a188f464441d6949c51493a2b7596 | DELETE {{baseUrl}}/system/oauth2/token?token=ca8a188f464441d6949c51493a2b7596 | ||||||
| Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw== | Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw== | ||||||
| tenant-id: {{adminTenentId}} | tenant-id: {{adminTenentId}} | ||||||
|  | 
 | ||||||
|  | ### 请求 /system/oauth2/check-token 接口 => 成功 | ||||||
|  | POST {{baseUrl}}/system/oauth2/check-token?token=620d307c5b4148df8a98dd6c6c547106 | ||||||
|  | Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw== | ||||||
|  | tenant-id: {{adminTenentId}} | ||||||
| @@ -10,6 +10,7 @@ import cn.iocoder.yudao.framework.common.util.http.HttpUtils; | |||||||
| import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||||||
| import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | ||||||
| import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO; | import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO; | ||||||
|  | import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenCheckTokenRespVO; | ||||||
| import cn.iocoder.yudao.module.system.convert.oauth2.OAuth2OpenConvert; | import cn.iocoder.yudao.module.system.convert.oauth2.OAuth2OpenConvert; | ||||||
| import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO; | import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO; | ||||||
| import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2ClientDO; | import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2ClientDO; | ||||||
| @@ -17,6 +18,7 @@ import cn.iocoder.yudao.module.system.enums.auth.OAuth2GrantTypeEnum; | |||||||
| import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ApproveService; | import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ApproveService; | ||||||
| import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientService; | import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientService; | ||||||
| import cn.iocoder.yudao.module.system.service.oauth2.OAuth2GrantService; | import cn.iocoder.yudao.module.system.service.oauth2.OAuth2GrantService; | ||||||
|  | import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService; | ||||||
| import cn.iocoder.yudao.module.system.util.oauth2.OAuth2Utils; | import cn.iocoder.yudao.module.system.util.oauth2.OAuth2Utils; | ||||||
| import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||||
| import io.swagger.annotations.ApiImplicitParam; | import io.swagger.annotations.ApiImplicitParam; | ||||||
| @@ -45,14 +47,14 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti | |||||||
| @Slf4j | @Slf4j | ||||||
| public class OAuth2OpenController { | public class OAuth2OpenController { | ||||||
|  |  | ||||||
| //    POST oauth/check_token CheckTokenEndpoint |  | ||||||
|  |  | ||||||
|     @Resource |     @Resource | ||||||
|     private OAuth2GrantService oauth2GrantService; |     private OAuth2GrantService oauth2GrantService; | ||||||
|     @Resource |     @Resource | ||||||
|     private OAuth2ClientService oauth2ClientService; |     private OAuth2ClientService oauth2ClientService; | ||||||
|     @Resource |     @Resource | ||||||
|     private OAuth2ApproveService oauth2ApproveService; |     private OAuth2ApproveService oauth2ApproveService; | ||||||
|  |     @Resource | ||||||
|  |     private OAuth2TokenService oauth2TokenService; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 对应 Spring Security OAuth 的 TokenEndpoint 类的 postAccessToken 方法 |      * 对应 Spring Security OAuth 的 TokenEndpoint 类的 postAccessToken 方法 | ||||||
| @@ -130,9 +132,6 @@ public class OAuth2OpenController { | |||||||
|                                              @RequestParam("token") String token) { |                                              @RequestParam("token") String token) { | ||||||
|         // 校验客户端 |         // 校验客户端 | ||||||
|         String[] clientIdAndSecret = obtainBasicAuthorization(request); |         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], |         OAuth2ClientDO client = oauth2ClientService.validOAuthClientFromCache(clientIdAndSecret[0], clientIdAndSecret[1], | ||||||
|                 null, null, null); |                 null, null, null); | ||||||
|  |  | ||||||
| @@ -140,6 +139,26 @@ public class OAuth2OpenController { | |||||||
|         return success(oauth2GrantService.revokeToken(client.getClientId(), token)); |         return success(oauth2GrantService.revokeToken(client.getClientId(), token)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 对应 Spring Security OAuth 的 CheckTokenEndpoint 类的 checkToken 方法 | ||||||
|  |      */ | ||||||
|  |     @PostMapping("/check-token") | ||||||
|  |     @ApiOperation(value = "校验访问令牌") | ||||||
|  |     @ApiImplicitParam(name = "token", required = true, value = "访问令牌", example = "biu", dataTypeClass = String.class) | ||||||
|  |     @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | ||||||
|  |     public CommonResult<OAuth2OpenCheckTokenRespVO> checkToken(HttpServletRequest request, | ||||||
|  |                                                                @RequestParam("token") String token) { | ||||||
|  |         // 校验客户端 | ||||||
|  |         String[] clientIdAndSecret = obtainBasicAuthorization(request); | ||||||
|  |         OAuth2ClientDO client = oauth2ClientService.validOAuthClientFromCache(clientIdAndSecret[0], clientIdAndSecret[1], | ||||||
|  |                 null, null, null); | ||||||
|  |  | ||||||
|  |         // 校验令牌 | ||||||
|  |         OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.checkAccessToken(token); | ||||||
|  |         Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查 | ||||||
|  |         return success(OAuth2OpenConvert.INSTANCE.convert2(accessTokenDO)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     //    GET  oauth/authorize AuthorizationEndpoint TODO |     //    GET  oauth/authorize AuthorizationEndpoint TODO | ||||||
|     @GetMapping("/authorize") |     @GetMapping("/authorize") | ||||||
|     @ApiOperation(value = "获得授权信息", notes = "适合 code 授权码模式,或者 implicit 简化模式;在 authorize.vue 单点登录界面被【获取】调用") |     @ApiOperation(value = "获得授权信息", notes = "适合 code 授权码模式,或者 implicit 简化模式;在 authorize.vue 单点登录界面被【获取】调用") | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ import lombok.AllArgsConstructor; | |||||||
| import lombok.Data; | import lombok.Data; | ||||||
| import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||||
|  |  | ||||||
| @ApiModel("管理后台 - 访问令牌 Response VO") | @ApiModel("管理后台 - 【开放接口】访问令牌 Response VO") | ||||||
| @Data | @Data | ||||||
| @NoArgsConstructor | @NoArgsConstructor | ||||||
| @AllArgsConstructor | @AllArgsConstructor | ||||||
|   | |||||||
| @@ -0,0 +1,40 @@ | |||||||
|  | package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open; | ||||||
|  |  | ||||||
|  | import com.fasterxml.jackson.annotation.JsonProperty; | ||||||
|  | import io.swagger.annotations.ApiModel; | ||||||
|  | import io.swagger.annotations.ApiModelProperty; | ||||||
|  | import lombok.AllArgsConstructor; | ||||||
|  | import lombok.Data; | ||||||
|  | import lombok.NoArgsConstructor; | ||||||
|  |  | ||||||
|  | import java.util.Set; | ||||||
|  |  | ||||||
|  | @ApiModel("管理后台 - 【开放接口】校验令牌 Response VO") | ||||||
|  | @Data | ||||||
|  | @NoArgsConstructor | ||||||
|  | @AllArgsConstructor | ||||||
|  | public class OAuth2OpenCheckTokenRespVO { | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "用户编号", required = true, example = "666") | ||||||
|  |     @JsonProperty("user_id") | ||||||
|  |     private Long userId; | ||||||
|  |     @ApiModelProperty(value = "用户类型", required = true, example = "2", notes = "参见 UserTypeEnum 枚举") | ||||||
|  |     @JsonProperty("user_type") | ||||||
|  |     private Integer userType; | ||||||
|  |     @ApiModelProperty(value = "租户编号", required = true, example = "1024") | ||||||
|  |     @JsonProperty("tenant_id") | ||||||
|  |     private Long tenantId; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "客户端编号", required = true, example = "car") | ||||||
|  |     private String clientId; | ||||||
|  |     @ApiModelProperty(value = "授权范围", required = true, example = "user_info") | ||||||
|  |     private Set<String> scopes; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "访问令牌", required = true, example = "tudou") | ||||||
|  |     @JsonProperty("access_token") | ||||||
|  |     private String accessToken; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "过期时间", required = true, example = "1593092157", notes = "时间戳 / 1000,即单位:秒") | ||||||
|  |     @JsonProperty("exp") | ||||||
|  |     private Long exp; | ||||||
|  | } | ||||||
| @@ -1,7 +1,9 @@ | |||||||
| package cn.iocoder.yudao.module.system.convert.oauth2; | package cn.iocoder.yudao.module.system.convert.oauth2; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | ||||||
| import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; | import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; | ||||||
| import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO; | import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO; | ||||||
|  | import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenCheckTokenRespVO; | ||||||
| import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO; | import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO; | ||||||
| import cn.iocoder.yudao.module.system.util.oauth2.OAuth2Utils; | import cn.iocoder.yudao.module.system.util.oauth2.OAuth2Utils; | ||||||
| import org.mapstruct.Mapper; | import org.mapstruct.Mapper; | ||||||
| @@ -19,7 +21,14 @@ public interface OAuth2OpenConvert { | |||||||
|         respVO.setScope(OAuth2Utils.buildScopeStr(bean.getScopes())); |         respVO.setScope(OAuth2Utils.buildScopeStr(bean.getScopes())); | ||||||
|         return respVO; |         return respVO; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     OAuth2OpenAccessTokenRespVO convert0(OAuth2AccessTokenDO bean); |     OAuth2OpenAccessTokenRespVO convert0(OAuth2AccessTokenDO bean); | ||||||
|  |  | ||||||
|  |     default OAuth2OpenCheckTokenRespVO convert2(OAuth2AccessTokenDO bean) { | ||||||
|  |         OAuth2OpenCheckTokenRespVO respVO = convert3(bean); | ||||||
|  |         respVO.setExp(bean.getExpiresTime().getTime() / 1000L); | ||||||
|  |         respVO.setUserType(UserTypeEnum.ADMIN.getValue()); | ||||||
|  |         return respVO; | ||||||
|  |     } | ||||||
|  |     OAuth2OpenCheckTokenRespVO convert3(OAuth2AccessTokenDO bean); | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ public class SecurityConfiguration { | |||||||
|                 registry.antMatchers(buildAdminApi("/system/sms/callback/**")).permitAll(); |                 registry.antMatchers(buildAdminApi("/system/sms/callback/**")).permitAll(); | ||||||
|                 // OAuth2 API |                 // OAuth2 API | ||||||
|                 registry.antMatchers(buildAdminApi("/system/oauth2/token")).permitAll(); |                 registry.antMatchers(buildAdminApi("/system/oauth2/token")).permitAll(); | ||||||
|                 registry.antMatchers(buildAdminApi("/system/oauth2/check_token")).permitAll(); |                 registry.antMatchers(buildAdminApi("/system/oauth2/check-token")).permitAll(); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|         }; |         }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV