Spring Security OAuth 格式化 token 輸出

個性化token 背景

上一篇文章《Spring Security OAuth 個性化token(一)》有提到,oauth2.0 接口默認返回的報文格式以下:git

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

經過上篇文章咱們已經能夠擴展增長部分業務字段。spring

{  
    "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業務碼信息」json

{  
    "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協議 致使其餘組件不能正常使用 例如app

  • swagger 自帶的認證受權

  • 其餘網關組件自帶的oauth2

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

  • spring security oauth2 自帶的 sso 功能

都將失效整體來權衡 弊大於利post

項目推薦: Spring Cloud 、Spring Security OAuth2的RBAC權限管理系統 歡迎關注ui

相關文章
相關標籤/搜索