zoukankan      html  css  js  c++  java
  • 关于Oauth2的微服务接口:正常数据和异常数据如何自定义统一的数据格式

    在基于Oauth2的微服务项目中,往往希望有统一格式的数据返回,包括以下四种情况:

    • Oauth2异常数据的封装
      {
          "code": 0,
          "message": "请求失败",
          "result": "无效token"
      }  
    • Oauth2正常数据的封装
      {
          "code": 1,
          "message": "请求成功",
          "result": {
              "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",
              "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",
              "exp": "1596721265802"
          }
      }
    • 接口异常数据的封装
      {
          "code": 0,
          "message": "请求失败",
          "result": "异常信息"
      }
    • 接口正常数据的封装
      {
          "code": 1,
          "message": "请求成功",
          "result": "接口数据"
      } 

    针对上述四种情况进行处理:

    1.Oauth2异常数据的封装:

    是四种情况中相对最为复杂的部分:分为认证服务器的异常信息处理和资源服务器的异常信息处理

    1.1认证服务器的异常信息处理(通常是获取token时抛出的异常)

    ①需要在AuthorizationServerConfigurerAdapter的AuthorizationServerEndpointsConfigurer进行配置

       endpoints.exceptionTranslator(customWebResponseExceptionTranslator)//自定义异常处理
       //配置WebResponseExceptionTranslator自定义异常,并重写translate方法返回自定义Oauth2认证异常信息

    ②由于在AuthorizationServerEndpointsConfigurer无法重写客户端配置信息异常,需要进行另行处理

     需要在AuthorizationServerConfigurerAdapter的AuthorizationServerSecurityConfigurer进行配置  

       CustomClientCredentialsTokenEndpointFilter endpointFilter = new CustomClientCredentialsTokenEndpointFilter(security);
       endpointFilter.afterPropertiesSet();
       endpointFilter.setAuthenticationEntryPoint(customAuthenticationEntryPoint);
       security.addTokenEndpointAuthenticationFilter(endpointFilter);//自定义异常过滤器和客户端端点过滤器
       //配置ClientCredentialsTokenEndpointFilter自定义过滤器,并加入AuthenticationEntryPoint重写commence方法,自定义返回Oauth2异常信息。

    1.2资源服务器的异常信息处理(验证token时抛出的异常):包括认证异常和授权异常的配置

       //在资源服务器ResourceServerConfigurerAdapter的ResourceServerSecurityConfigurer中配置
       resources.authenticationEntryPoint(customAuthExceptionEntryPoint)//认证异常处理类
       resources.accessDeniedHandler(customAccessDeniedHandler)//权限异常处理类

    配置认证异常处理AuthenticationEntryPoint,重写commence方法,自定义Oauth2异常信息。

    配置授权异常处理AccessDeniedHandler,重写handle方法,自定义Oauth2异常信息。

    2.Oauth2正常数据的封装

    使用aop重写oauth2的TokenEndpoint.postAccessToken结果

      //类注解@Component和@Aspect
      @Around("execution(* org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(..))")
      //获取原有方法返回值为ResponseEntity<OAuth2AccessToken> responseEntity 
      //将responseEntity 中需要的信息放入map中,返回
      return ResponseEntity.status(HttpStatus.OK).body(map);
      //这里直接返回map,数据格式会在后续统一处理。
      //同样如果需要也可以通过aop重写CheckTokenEndpoint.checkToken

    3.接口异常数据和正常数据的封装 

    //这里为了方便将异常和数据放在一起进行处理(RestResponse为定义的统一数据类)
      @ControllerAdvice
      public class GlobalExceptionHandler implements ResponseBodyAdvice {
        private ObjectMapper objectMapper = new ObjectMapper();
       //统一异常处理
      @ExceptionHandler(value = Exception.class)
      @ResponseBody
      public RestResponse<Object> exceptionHandler(HttpServletRequest req, Exception e){
      return RestResponse.failure(e.getMessage());
      }
    
       //统一数据处理
      @Override
      public boolean supports(MethodParameter methodParameter, Class aClass) {
      return true;
      }
      
      @Override
      public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass,
        ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {   
    //String类型返回会发生类型转换异常,额外处理     if (o instanceof String) {       try {         serverHttpResponse.getHeaders().set("Content-Type", "application/json;charset=utf-8");         return objectMapper.writeValueAsString(RestResponse.success(o));       } catch (JsonProcessingException e) {         e.printStackTrace();       }     }else if(o instanceof RestResponse){       //原有部分接口已经使用RestResponse包装过,防止重复包装。       return o;     }     //统一数据包装,包括Oauth2的正常数据(Oauth2的异常数据已经直接),Oauth2的异常数据已经直接httpServletResponse.getWriter().write()不需要处理     return RestResponse.success(o);    } }

    4.总结

    整理总结了在处理基于Oauth2的微服务接口中,正常数据和异常数据自定义统一数据格式的问题。

  • 相关阅读:
    BGP协议
    OSPF协议项目实战
    理解Eth-Trunk
    二层交换网络当中的高级内容
    策略路由
    isis综合作业
    mac 上安装brew,permission denied解决,安装pip, 安装 requests
    [随笔]swift 笔记
    [转]Swift
    [汇] Android 知识汇总
  • 原文地址:https://www.cnblogs.com/masting/p/13445179.html
Copyright © 2011-2022 走看看