spring - 为什么我的 JdbcTokenStore 存储序列化 Java 对象?
问题描述
所以我只是从 移动InMemoryTokenStore
到JdbcTokenStore
。像往常一样,一个看似简单的更改之后会出现一些副作用,包括吞下异常 - 很抱歉咆哮。
这就是我用来访问用户主体的方式:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = (String) authentication.getPrincipal();
第一的
出于某种原因,getPrincipal()
总是只返回用户名而不是UserDetails
对象。这对我来说已经足够好了,所以我就去了。
现在我更改了令牌存储,getPrincipal()
确实返回了UserDetails
对象。我可以忍受,但我想知道为什么这会突然改变 - 我必须重构一些代码,因为从getPrincipal()
现在开始我一直期望用户名。我也想知道我是否可以改变这一点。
第二
从我所见,JdbcTokenStore
似乎序列化 Java 对象。它试图序列化一个Token
对象和一个UserDetails
对象。这些列似乎代表了那些序列token
化authentication
的对象,我想了解为什么这实际上是必要的。毕竟这是可以在启动/运行时从数据库中恢复的信息。当然除了Token
,但我不明白为什么他们不只存储令牌(the String
)而是存储对象。
最重要的是:对这些类中的任何一个进行最轻微的更改,它们都不会被反序列化!如果其中一个类被更改,那么每个用户都将被迫重新登录,这违背了我JdbcTokenStore
首先要使用的原因 - 所以一定有一些可疑的东西,否则我没有得到它。
也许有人可以对此有所了解。
解决方案
看着你的咆哮,然后看着你的代码,我也有点惊讶!它在幕后所做的实际上是将对象(就像你建议的那样!)序列化为一个看起来非常不友好的对象字符串:
protected byte[] serializeAccessToken(OAuth2AccessToken token) {
return SerializationUtils.serialize(token);
}
看起来应该做什么(我不确定他们为什么不在文档中指出这一点)是覆盖以下*serialize
方法JdbcTokenStore
:
protected OAuth2AccessToken deserializeAccessToken(byte[] token)
protected OAuth2Authentication deserializeAuthentication(byte[] authentication)
protected OAuth2RefreshToken deserializeRefreshToken(byte[] token)
protected byte[] serializeAccessToken(OAuth2AccessToken token)
protected byte[] serializeAuthentication(OAuth2Authentication authentication)
protected byte[] serializeRefreshToken(OAuth2RefreshToken token)
这可能就是为什么他们都受到保护。实现可能如下所示:
class JacksonJdbcTokenStore extends JdbcTokenStore {
private ObjectMapper mapper;
public JdbcTokenStore(ObjectMapper mapper, DataSource dataSource) {
this.mapper = mapper;
super(dataSource);
}
protected byte[] serializeAuthentication(OAuth2Authentication authentication)
{
return mapper.writeValueAsBytes(authentication);
}
protected OAuth2Authentication deserializeAuthentication(byte[] authentication) {
return mapper.read(authentication, OAuth2Authentication.class);
}
// Same type of thing for the other serialize/deserialize operations...
}
我实际上并没有尝试或测试过上面的代码,你可能不得不摆弄序列化规则,但我只能告诉你。
对于这种奇怪的默认行为的奇怪之处,我可以同情你,但我不明白你为什么会在这里做错事。这是我能说的最好的!
仅供参考,对于第一个问题,我对这些不同的实现可能返回不同Principal
的 's 并不感到惊讶,这对于实现来说是正常的,而Authentication
这正是 Spring 的做法。
推荐阅读
- ios - iOS - Alamofire - 无法通过 WiFi 访问服务器
- java - 如何调用内联类中创建的方法
- python - 我如何运行这个程序我是新来的 oops
- android - 如何正确检测应用内购买是否已退款?
- amazon-web-services - Redshift 查询限制为 100 mb
- docker - 添加日志记录选项时,Docker Compose 不起作用
- javascript - TypeError:无法使用 TypeDi 读取未定义的属性“authService”
- floating-point - 具有替代测量单位的定点/整数表示的名称
- python - 如何修复:“HadoopFileSystem 加载错误:libhdfs.so:无法打开共享对象文件:没有这样的文件或目录 10:49:33 Traceback”?
- report - 如何生成排毒测试报告?