Spring Security OAuth format token output

Keywords: Programming Spring

Personalized token background

Last article Spring Security OAuth personalized token (I) It is mentioned that the default message format returned by oauth2.0 interface is as follows:

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

Through the previous article, we have been able to expand and add some business fields.

{  
    "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"  
}  

"In some scenarios, we need to customize the format of the return message. For example, pig uses R object to return, all of which contains code business code information."

{  
    "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"  
    }  
}  

Method 1: HandlerMethodReturnValueHandler

  • As the name implies, this is the interface provided by Spring MVC to modify the return value of methods
public class FormatterToken implements HandlerMethodReturnValueHandler {  
  
 private static final String POST_ACCESS_TOKEN = "postAccessToken";  
  
 @Override  
 public boolean supportsReturnType(MethodParameter returnType) {  
     //To determine whether the method name is the token interface of oauth2, handle  
  return POST_ACCESS_TOKEN.equals(Objects  
    .requireNonNull(returnType.getMethod()).getName());  
 }  
    
  //Get the return value and wrap it uniformly with R object  
 @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));  
 }  
}  
  • To inject FormatterToken, do this. Do not use MVCconfig injection directly to ensure that the Handler executes ahead of spring MVC by default.
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;  
 }  
}  

Method 2: aop interception enhanced / oauth/token interface

@Around("execution(* org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(..))")  
public Object handlePostAccessTokenMethod(ProceedingJoinPoint joinPoint) throws Throwable {  
   //Get the original value and return the package  
      Object proceed = joinPoint.proceed();  
  
      ResponseEntity<OAuth2AccessToken> responseEntity = (ResponseEntity<OAuth2AccessToken>) proceed;  
        OAuth2AccessToken body = responseEntity.getBody();  
        return ResponseEntity  
                  .status(HttpStatus.OK)  
                  .body(R.ok(body));  
        }  
}  

summary

In the actual project, it is not recommended to modify the access format of this interface, which is incompatible with oauth2 protocol, so other components cannot be used normally. For example

  • Authentication and authorization of swagger

  • oauth2 provided by other gateway components

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

  • sso function of spring security oauth2

All of them will fail, so as to weigh the advantages against the disadvantages

Project recommendation: Welcome to RBAC permission management system of Spring Cloud and Spring Security OAuth2

Posted by Mohammad on Tue, 21 Apr 2020 09:24:02 -0700