乐趣区

关于java:一个接口优雅的实现-Spring-Cloud-OAuth2-自定义token返回格式

大家好,我是不才陈某~

最近订阅《Spring Cloud Alibaba 我的项目实战》的敌人针对 Spring Security OAuth2.0 想要陈某补充一些常识,如下:

明天这篇文章就来答复其中一个问题:如何自定义 token 的返回格局?

问题形容

Spring Security OAuth 的 token 返回格局都是默认的,然而往往这个格局是不适配零碎,/oauth/token返回的格局如下:

{
    "access_token": token
    "token_type": "bearer",
    "refresh_token": xxxx
    "expires_in": xxx,
    "scope": "xxx",
    "jti": xxxx
    ....................
}

然而此时零碎中的对立返回格局为:

{
    "code":xxx
    "data":xxx
    "msg":xxx
}

那么如何去对默认的格局进行批改呢?

解决方案

其实解决方案还是很多的,据陈某理解有如下两种解决方案:

  1. 应用 AOP 的形式对 /oauth/token 这个接口的后果拦挡批改
  2. 重定义接口笼罩默认的

第一种计划呢能够实现,然而对于陈某来说不够优雅,实现比较简单,不显逼格

于是陈某明天介绍第二种计划,一种比拟优雅的形式;想要了解第二种形式必须对 Spring Security 的底层源码有一些理解。

/oauth/token这个接口定义在哪里呢?通过源码咱们晓得定义在 org.springframework.security.oauth2.provider.endpoint.TokenEndpoint 中,如下:

@RequestMapping(value = "/oauth/token", method=RequestMethod.GET)
public ResponseEntity<OAuth2AccessToken> getAccessToken(Principal principal, @RequestParam
Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {}

@RequestMapping(value = "/oauth/token", method=RequestMethod.POST)
public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam
Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {}

能够看到针对这个接口定义了两个,一个是 GET 申请、一个是 POST 申请

TokenEndpoint其实就是一个接口,应用注解 @FrameworkEndpoint 标注,这个注解和 @Controller 的作用一样,如下:

@FrameworkEndpoint
public class TokenEndpoint extends AbstractEndpoint {}

那么晓得在哪里定义的就好办了,模拟着它这个接口本人从新定义一个笼罩掉不就好了,如下:

@Api(value = "OAuth 接口")
@RestController
@RequestMapping("/oauth")
@Slf4j
public class AuthController implements InitializingBean {

    // 令牌申请的端点
    @Autowired
    private TokenEndpoint tokenEndpoint;

    // 自定义异样翻译器,针对用户名、明码异样,受权类型不反对的异样进行解决
    private OAuthServerWebResponseExceptionTranslator translate;

    /**
     * 重写 /oauth/token 这个默认接口,返回的数据格式对立
     */
    @PostMapping(value = "/token")
    public ResultMsg<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam
            Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {OAuth2AccessToken accessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
        return ResultMsg.resultSuccess(accessToken);
    }
}

能够看到接口外部不须要本人重写逻辑,只须要调用 TokenEndpoint 中的办法

留神:因为对 TokenEndpoint 中的端点重写了,因而后面定义的对用户名、明码之类的异样捕捉的翻译类(OAuthServerWebResponseExceptionTranslator)将会生效,须要在全局异样中进行捕捉

下面是 /oauth/token 的接口,/oauth/check_token这个校验 token 的接口如需自定义也是能够的,对应的类是org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint

重写后代码如下:

@Api(value = "OAuth 接口")
@RestController
@RequestMapping("/oauth")
@Slf4j
public class AuthController implements InitializingBean {

    @Autowired
    private CheckTokenEndpoint checkTokenEndpoint;

    // 自定义异样翻译器,针对用户名、明码异样,受权类型不反对的异样进行解决
    private OAuthServerWebResponseExceptionTranslator translate;
    
    /**
     * 重写 /oauth/check_token 这个默认接口,用于校验令牌,返回的数据格式对立
     */
    @PostMapping(value = "/check_token")
    public ResultMsg<Map<String,?>> checkToken(@RequestParam("token") String value)  {Map<String, ?> map = checkTokenEndpoint.checkToken(value);
        return ResultMsg.resultSuccess(map);
    }

这种形式是不是很优雅?也很合乎 Spring Security 的设计思维,AOP 的形式还要对参数解析,从新包装

好了,对于测试的话本人搞一搞

总结

本篇文章介绍了认证服务中对 token 的返回格局自定义,总的来说还是比较简单的,有趣味的也能够去网上找找对于 AOP 的形式。

退出移动版