不想看分析过称的 ,文章结尾就是解决方法
OAuth2 虽然公司项目用了,但只是浅尝辄止,今天自己搭了一下服务,出现这么一个问题。
我是用RedisTokenStore存储token refresh token,在redisTokenStore 存储的时候,会把要存储的对象序列化变成byte数组放到redis里面。
这个地方就出问题了。
具体的提示是:
Resolved [org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: org.springframework.dao.support.PersistenceExceptionTranslationInterceptor]
解决问题
debug了一下源码,发现是在序列化OAuth2Authentication的时候 有了问题,很奇怪,这里使用的JDK的序列化,没道理会出错的,
重点是: 我的另外一个项目序列化的时候 是没问题的!
仔细对比了一下,最终发现原因
原因
OAuth2Authentication会持有一个Authentication引用,这个可以从它的构造方法得知,这个Authentication是我们前面的filter chain里面认证对象时候产生的。Authentication的GrantedAuthority,是
UserDetails提供的。他们之间有引用的关系。
/**
* Construct an OAuth 2 authentication. Since some grant types don't require user authentication, the user
* authentication may be null.
*
* @param storedRequest The authorization request (must not be null).
* @param userAuthentication The user authentication (possibly null).
*/
public OAuth2Authentication(OAuth2Request storedRequest, Authentication userAuthentication) {
super(userAuthentication == null ? storedRequest.getAuthorities() : userAuthentication.getAuthorities());
this.storedRequest = storedRequest;
this.userAuthentication = userAuthentication;
}
我这个项目里面的UserDetails是我自己扩展的
代码如下
package com.example.sercurity.bo;
import com.example.sercurity.entity.Role;
import com.example.sercurity.entity.User;
import com.example.sercurity.service.PermissonService;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority