Spring Security OAuth 格式化 token 输出

2020-06-08 16:05:39来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

Spring Security OAuth 格式化 token 输出

个性化token 背景

上一篇文章《Spring Security OAuth 个性化token(一)》有提到,oauth2.0 接口默认返回的报文格式如下:

{  
????"access_token":?"e6669cdf-b6cd-43fe-af5c-f91a65041382",  
????"token_type":?"bearer",  
????"refresh_token":?"da91294d-446c-4a89-bdcf-88aee15a75e8",  
????"expires_in":?43199,?  
????"scope":?"server"  
}  

通过上篇文章我们已经可以扩展增加部分业务字段。

{  
????"access_token":"a6f3b6d6-93e6-4eb8-a97d-3ae72240a7b0",  
????"token_type":"bearer",  
????"refresh_token":"710ab162-a482-41cd-8bad-26456af38e4f",  
????"expires_in":42396,  
????"scope":"server",  
????"tenant_id":1,  
????"license":"made?by?pigx",  
????"dept_id":1,  
????"user_id":1,  
????"username":"admin"  
}  

「在一些场景下我们需要自定义一下返回报文的格式,例如pig 使用R 对象返回,全部包含code业务码信息」

{  
????"code":1,  
????"msg":"",  
????"data":{  
????????"access_token":"e6669cdf-b6cd-43fe-af5c-f91a65041382",  
????????"token_type":"bearer",  
????????"refresh_token":"da91294d-446c-4a89-bdcf-88aee15a75e8",  
????????"expires_in":43199,  
????????"scope":"server"  
????}  
}  

方法一:HandlerMethodReturnValueHandler

  • 顾名思义这是 Spring MVC 提供给我们修改方法返回值的接口
public?class?FormatterToken?implements?HandlerMethodReturnValueHandler?{  
  
?private?static?final?String?POST_ACCESS_TOKEN?=?"postAccessToken";  
  
?@Override  
?public?boolean?supportsReturnType(MethodParameter?returnType)?{  
?????//?判断方法名是否是?oauth2?的token?接口,是就处理  
??return?POST_ACCESS_TOKEN.equals(Objects  
????.requireNonNull(returnType.getMethod()).getName());  
?}  
??  
??//?获取到返回值然后使用?R对象统一包装  
?@Override  
?public?void?handleReturnValue(Object?returnValue,?MethodParameter?returnType,?ModelAndViewContainer?container,?NativeWebRequest?request)?throws?Exception?{  
??ResponseEntity<OAuth2AccessToken>?responseEntity?=?(ResponseEntity)?returnValue;  
??OAuth2AccessToken?body?=?responseEntity.getBody();  
  
??HttpServletResponse?response?=?request.getNativeResponse(HttpServletResponse.class);  
??assert?response?!=?null;  
??WebUtils.renderJson(response,?R.ok(body));  
?}  
}  
  • 注入FormatterToken,一定要这么处理,不要直接使用 MVCconfig 注入,保证此Handler比 SpringMVC 默认的提前执行。
public?class?FormatterTokenAutoConfiguration?implements?ApplicationContextAware,?InitializingBean?{  
?private?ApplicationContext?applicationContext;  
  
?@Override  
?public?void?afterPropertiesSet()?{  
??RequestMappingHandlerAdapter?handlerAdapter?=?applicationContext.getBean(RequestMappingHandlerAdapter.class);  
??List<HandlerMethodReturnValueHandler>?returnValueHandlers?=?handlerAdapter.getReturnValueHandlers();  
  
??List<HandlerMethodReturnValueHandler>?newHandlers?=?new?ArrayList<>();  
??newHandlers.add(new?FormatterToken());  
??assert?returnValueHandlers?!=?null;  
??newHandlers.addAll(returnValueHandlers);  
??handlerAdapter.setReturnValueHandlers(newHandlers);  
?}  
  
?@Override  
?public?void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException?{  
??this.applicationContext?=?applicationContext;  
?}  
}  

方法二:aop 拦截增强 /oauth/token 接口

@Around("execution(*?org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(..))")  
public?Object?handlePostAccessTokenMethod(ProceedingJoinPoint?joinPoint)?throws?Throwable?{  
???//?获取原有值,进行包装返回  
??????Object?proceed?=?joinPoint.proceed();  
  
??????ResponseEntity<OAuth2AccessToken>?responseEntity?=?(ResponseEntity<OAuth2AccessToken>)?proceed;  
????????OAuth2AccessToken?body?=?responseEntity.getBody();  
????????return?ResponseEntity  
??????????????????.status(HttpStatus.OK)  
??????????????????.body(R.ok(body));  
????????}  
}  

总结

实际项目中不建议修改此接口的访问格式,不兼容oauth2协议 导致其他组件不能正常使用 例如

  • swagger 自带的认证授权

  • 其他网关组件自带的oauth2

https://docs.konghq.com/hub/kong-inc/oauth2/

  • spring security oauth2 自带的 sso 功能

都将失效总体来权衡 弊大于利

项目推荐: Spring Cloud 、Spring Security OAuth2的RBAC权限管理系统 欢迎关注


原文链接:https://www.cnblogs.com/leng-leng/p/13064878.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:面试的时候按照这个套路回答 Java GC 的相关问题一定能过

下一篇:这可能是目前最透彻的Netty讲解了...