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

开发 前端
本篇文章介绍了认证服务中对token的返回格式自定义,总的来说还是比较简单的,有兴趣的也可以去网上找找关于AOP的方式。

今天这篇文章就来回答其中一个问题:如何自定义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
}

那么如何去对默认的格式进行修改呢?

解决方案

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

  • 使用AOP的方式对/oauth/token这个接口的结果拦截修改;
  • 重定义接口覆盖默认的;

第一种方案呢可以实现,但是对于陈某来说不够优雅,实现比较简单,不显逼格。

于是陈某今天介绍第二种方案,一种比较优雅的方式;想要理解第二种方式必须对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的方式。

责任编辑:武晓燕 来源: 码猿技术专栏
相关推荐

2022-04-11 07:34:46

OAuth2UAA节点

2021-02-04 09:18:20

服务器认证自定义

2021-08-02 12:50:45

sessiontokenJava

2022-06-06 09:28:36

ReactHook

2022-06-29 08:37:11

授权码模式底层

2020-09-18 10:12:24

KotlinTCP网络协议

2022-06-21 14:44:38

接口数据脱敏

2024-11-08 15:56:36

2024-11-07 10:55:26

2012-11-19 11:07:42

IBMdw

2023-08-31 08:34:07

Users对象序列化

2023-08-29 08:00:38

2010-02-25 11:23:29

WCF返回自定义格式

2011-04-11 13:14:58

AjaxWEB服务

2015-02-12 15:33:43

微信SDK

2022-03-07 07:33:24

Spring自定义机制线程池

2009-08-21 15:38:45

ControllerF

2021-11-15 13:58:00

服务器配置授权

2009-04-28 13:25:36

Ajax函数Java

2023-08-01 08:54:02

接口幂等网络
点赞
收藏

51CTO技术栈公众号