记录Spring Security OAuth2.0认证授权7:前后端代码分离

本文主要介绍了在Spring Security OAuth2.0认证授权中遇到的jwt令牌过期校验和refresh-token更新令牌缺少用户信息的问题。通过在网关处增加过期时间校验以及调整JwtAccessTokenConverter的配置,解决了jwt令牌永不过期和refresh-token更新时用户信息丢失的难题。此外,还介绍了如何新建business-server模块实现前后端分离,以及登录、刷新token的前端实现。最后提供了测试步骤和源代码地址。
摘要由CSDN通过智能技术生成

一、jwt令牌在网关处的过期时间校验
二、refresh-token接口缺少用户信息
三、新建business-server模块作为web容器
四、前后端分离
1、关闭认证服务表单登录
2、前后端代码
五、测试
六、源代码地址
历史文章

Spring Security OAuth2.0认证授权一:框架搭建和认证测试
Spring Security OAuth2.0认证授权二:搭建资源服务
Spring Security OAuth2.0认证授权三:使用JWT令牌
Spring Security OAuth2.0认证授权四:分布式系统认证授权
Spring Security OAuth2.0认证授权五:用户信息扩展到jwt

本篇文章将会解决上一篇文章《Spring Security OAuth2.0认证授权五:用户信息扩展到jwt 》中遗留的问题,并在原有的项目中新增模块business-server用来充当前端页面的web容器并转发登录请求和更换token的请求等,以模拟前后端分离下的登录以及更换token操作。

一、jwt令牌在网关处的过期时间校验
上一篇文章中讲了在网关处解析token并转发到目标服务的操作,因为使用了jwt令牌的原因,所以省了一步到认证服务器认证的操作,只要验签成功,就认为令牌有效。这实际上留下了一个bug:服务端无法主动取消jwt令牌,所以这个令牌只要客户端保存下来,如果不调用认证服务器的令牌验证接口,这个jwt令牌将永远有效。因此需要在网关处加上对过期时间的校验。

在TokenFilter中添加以下代码逻辑

//取出exp字段,判断token是否已经过期
try {
Map<String, Object> map = objectMapper.readValue(payLoad, new TypeReference<Map<String, Object>>() {
});
long expiration = ((Integer) map.get(“exp”)) * 1000L;
if (expiration < new Date().getTime()) {
return unAuthorized(exchange, “未认证的请求:token存在,但是已经失效”,WrapperResult.TOKEN_EXPIRE);
}
} catch (IOException e) {
log.error("", e);
return unAuthorized(exchange, “未认证的请求:错误的token”,null);
}
二、refresh-token接口缺少用户信息
refresh-token在access_token过期,但是refresh-token未过期的时候使用,目的是使用refresh_token更新已经过期的access_token,这样理论上来说,客户端只要能在refresh_token过期之前进行任意操作,就可以避免重新登录了。

上一篇文章中将用户信息放到了jwt token中并返回给客户端,但是如果使用refresh_token更新token,后端会报错,前端取到的token中则缺少了用户信息。究其原因,和JwtAccessTokenConverter有关系,关于这个类的实例,当初创建的方法如下

@Bean
public JwtAccessTokenConverter accessTokenConverter(){
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
jwtAccessTokenConverter.setSigningKey(SIGNING_KEY);//对称秘钥,资源服务器使用该秘钥来验证
return jwtAccessTokenConverter;
}
这里的new操作省了很多默认参数的指定,且先看下为啥会缺少用户信息,扩展用户信息的关键在于方法com.kdyzm.spring.security.auth.center.service.MyUserDetailsServiceImpl#loadUserByUsername,这里扩展了用户信息,使其从单纯的username字符串变成了UserDetailsExpand对象,然后在增强方法com.kdyzm.spring.security.auth.center.enhancer.CustomTokenEnhancer#enhance中将扩展信息取出来放到Token中。

经过debug,发现

2021-01-29_162556.jpg

最终发现是如下代码的问题org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter#extractAuthentication

public Authentication extractAuthentication(Map<String, ?> map) {
if (map.containsKey(USERNAME))

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值