zoukankan      html  css  js  c++  java
  • 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权限管理系统 欢迎关注

  • 相关阅读:
    Raspberry Pi + ArchLinux:网络dhcp不稳定,经常无法获取IP地址
    Chromium OS相比Chrome OS缩水的地方
    ssh config配置更新
    ktouch w619: Dump boot.img和system.img,然后做成recovery可用的刷机zip包
    mmap: invalid argument & MAP_PRIVATE
    Ubuntu 12.04 fcitx已经可以aptget,并且默认是是Google拼音的词库
    epoll_create, epoll_ctl和epoll_wait 实例讲解
    VM上安装Redhat无法选包
    关于Segmentation fault (core dumped)几个简单问题的整理
    Linux字符串转换函数汇总
  • 原文地址:https://www.cnblogs.com/leng-leng/p/13064878.html
Copyright © 2011-2022 走看看