SpringSecurityOauth2:RedisTokenStore(一)之Token内容揭秘

更新时间:2023-06-29 05:16:09 阅读: 评论:0

SpringSecurityOauth2:RedisTokenStore(⼀)之Token内容揭秘
[本⽂仅仅作为⾃我学习的笔记,有什么不对或误⼈之处,望⼤佬指正]
RedisTokenStore之Token内容揭秘
Token存储⽅式
Spring Security Oauth2 存储Token的⽅式有多种, ⽐如JWT、Jdbc(数据库)、Redis等,根据Oauth2继承类图,实现⽅式如下:
使⽤Redis存储Token具有明显的优势,我⾃⼰开发学习的过程使⽤RedisTokenStore。
Redis key存储内容
在使⽤Redis存储token,spring curity oauth2 会⽣成以下⼏个key, 直接放出RedisTokenStore的源码吧:
private static final String ACCESS ="access:";
private static final String AUTH_TO_ACCESS ="auth_to_access:";
private static final String AUTH ="auth:";
private static final String REFRESH_AUTH ="refresh_auth:";
private static final String ACCESS_TO_REFRESH ="access_to_refresh:";
马文婷
private static final String REFRESH ="refresh:";
private static final String REFRESH_TO_ACCESS ="refresh_to_access:";
private static final String CLIENT_ID_TO_ACCESS ="client_id_to_access:";
private static final String UNAME_TO_ACCESS ="uname_to_access:";
这⼏个存储的key都存了什么内容,有什么含义呢?
于是我打开redis-cli,迫不及待的看⼀下这个key “shield:oauth:access:x8U6xmAK0MeFDEJ0”(“shield:oauth:”是项⽬⾃定义的前缀)
尼玛,这是什么东西?我们来看⼀下RedisTokenStore的源码:
//spring cuity oauth2提供的⼀个序列化⼯具
private RedisTokenStoreSerializationStrategy rializationStrategy =new JdkSerializationStrategy();
//存储OAuth2AccessToken
public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication){
byte[] rializedAccessToken =rialize(token);
......
}
//把存储对象序列化
private byte[]rialize(Object object){
return rializationStrategy.rialize(object);
}
通过源码,我们发现spring curity oauth2存储的是序列化后的对象,⽽不是json。(注意:应该是
为提⾼存储效率,⽽不是加密操作)那我们就以access:[AccessToken]这个key为例,在⾃⼰项⽬⾥写⼀个controller看看这个对象内容(⾃⼰debug也⾏,junit单元测试也⾏,⾃⼰能看到内容就好)
@ApiOperation(value ="获取access存储内容", httpMethod ="GET")
@GetMapping("/derialize/access")
public R<Object>derializeAccessToken(
@ApiParam("accessToken")@NotBlank(message ="accessToken不能为空")@RequestParam("accessToken") String accessToken
){
RedisTokenStoreSerializationStrategy rializationStrategy =new JdkSerializationStrategy();
byte[] rializedKey = rializationStrategy.rialize(Prefix.REDIS_SHIELD_OAUTH2 +"access:"+ accessToken);
RedisConnection conn = Connection();
byte[] bytes;
try{
bytes = (rializedKey);
}finally{
conn.clo();
清炒芹菜的做法}
OAuth2AccessToken content = rializationStrategy.derialize(bytes, OAuth2AccessToken.class);
春雨植物
return RUtil.success(content);
}
经过这个controller,还原成我们常⽤的json格式,如下:
{
"access_token":"x8U6xmAK0MeFDEJ0",
"token_type":"bearer",
"refresh_token":"0qLDRZE70MeFDEI!",
"expires_in":29658,
"scope":"rver"
}
好了,既然我们key的内容知道了,我们就逐⼀分析⼀下这⼏个key的⽤处。
1. access:[AccessToken](对应对象:OAuth2AccessToken)
要如何获取这个key? 如果你已有spring curity oauth2的项⽬(如果没有,可以github或spring官⽹找⼀个sample项⽬或⾃⼰搭建⼀个),可以类似这样发送⼀个请求:
localhost:6799/oauth/token?grant_type=password&urname=wuji&password=12345678&client_id=app&client_cret=app
spring curity oauth2获取AccessToken如果是密码授权⽅式(grant_type=password)除了携带⽤户名以及密码还要携带client_id 和client_cret,当然,你也可以Http Basic⽅式将client_id和client_cret到请求头,如下:
YXBwOmFwcA==是“client_id:client_cret” ba64编码后的结果。
好了,我们试着发送⼀个请求,返回结果如下:
{
//token,拿着这个token我们就可以资源(接⼝)了
"access_token":"x8U6xmAK0MeFDEJ0",
//token类型是⼀个票据类型,还有授权码类型等等
"token_type":"bearer",
/
/⽤与刷新access_token(资源访问token)的token
"refresh_token":"0qLDRZE70MeFDEI!",
//access_token剩余存活时间(单位是秒)
"expires_in":29658,
//拿这个token可以访问那些范围内的资源
"scope":"rver"
}
2. auth_to_access:[这⾥不再是AccessToken]
通过阅读源码,发现:
public String extractKey(OAuth2Authentication authentication){
//省略⼀些代码
values.put(USERNAME, Name());
values.put(CLIENT_ID, ClientId());
values.put(SCOPE, OAuth2Utils.formatParameterList(new TreeSet<String>(Scope())));
return generateKey(values);
}
auth_to_access:key, key是将urname、client_id、scope三个值加密后的值,我们再看auth_to_access:存储的内容如下:
{
"access_token":"x8U6xmAK0MeFDEJ0",
"token_type":"bearer",
"refresh_token":"0qLDRZE70MeFDEI!",
"expires_in":24126,
"scope":"rver"
}
跟access:的内容⼀模⼀样,那我们就知道了,代码内部实现可以通过urname、client_id、scope 3个字段获取AccessToken。
3.auth:[accessToken] (对应对象:OAuth2Authentication)
auth:存的内容如下:
{
"authorities":[{
"authority":"ROLE_USER"
},
{
"authority":"USER_RETRIEVE"
}
],
"details":null,
"authenticated":true,
"urAuthentication":{
"authorities":[{
"authority":"ROLE_USER"
},
{
"authority":"USER_RETRIEVE"
}
],
"details":{
"client_cret":"app",
"grant_type":"password",
"client_id":"app",
"urname":"wuji"
},
"authenticated":true,
"principal":{
"password":null,
"urname":"wuji",
"authorities":[{
"authority":"ROLE_USER"
},
{
有去无回"authority":"USER_RETRIEVE"
}
],
"accountNonExpired":true,
"accountNonLocked":true,
"credentialsNonExpired":true,
"enabled":true
},
"credentials":null,
"name":"wuji"
},
"credentials":"",
"principal":{
"password":null,
"urname":"wuji",
"authorities":[{
"authority":"ROLE_USER"
},
{
"authority":"USER_RETRIEVE"
}
],
"accountNonExpired":true,
"accountNonLocked":true,
"credentialsNonExpired":true,
"enabled":true
},
鲍鱼鸡"oauth2Request":{
"oauth2Request":{
"clientId":"app",
"scope":["rver"],
"requestParameters":{
"grant_type":"password",
"client_id":"app",
"urname":"wuji"
},
"resourceIds":[],
"authorities":[],
"approved":true,
"refresh":fal,
"redirectUri":null,
"responTypes":[],
"extensions":{},
"grantType":"password",
"refreshTokenRequest":null
},
"clientOnly":fal,
"name":"wuji"
}
主要包含当前登录⽤户的信息,以及⽤户附带的⾓⾊和和权限信息、⽣成Token时的授权⽅式等信息。
4.access_to_refresh:[accessToken]
access_to_refresh:存储的内容很简单,在通过password等授权⽅式获取token时的refreshToken
//refresh_token
grz0Xlzi0MeQwkx9
淡斑面膜拿refreshToken去刷新accessToken时,会将新⽣成的accessToken放到refresh_to_access:
//access_token
美学图片TesxUOBt0MeRDDxA
存储内容如下:
{
/
/refresh_toekn
"value":"grz0Xlzi0MeQwkx9",
//过期时间戳(mills)
"expiration":1557821765322
给自己}
拿refreshToken去刷新accessToken时, 会先拿到这个KEY的信息,判断请求⽅的refresh token是否有效,⽆效的不能刷新access token。
refresh_auth:存的内容与auth:类似,如下:
{
"authorities":[
{
"authority":"ROLE_USER"
},
{
"authority":"USER_RETRIEVE"
}
],
"details":null,
"authenticated":true,

本文发布于:2023-06-29 05:16:09,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1064125.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:内容   信息   对象   请求   学习   授权
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图