所以我只是从InMemoryTokenStore
转到JdbcTokenStore
。像往常一样,一个看似简单的变化之后会出现一些副作用,其中包括吞咽的异常现象-十分抱歉。
这是我过去访问用户主体的方式:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = (String) authentication.getPrincipal();
由于某种原因,getPrincipal()
始终仅返回用户名而不是UserDetails
对象。这对我来说足够好了,所以我同意了。
现在我更改了令牌存储,getPrincipal()
确实确实返回了UserDetails
对象。我可以接受,但是我想知道为什么这突然改变了-因为我一直期望用户名从getPrincipal()
到现在,所以我不得不重构一些代码。我也想知道我是否可以更改它。
据我所见,JdbcTokenStore
似乎序列化了Java对象。它尝试序列化Token
对象和UserDetails
对象。 token
和authentication
列似乎代表了这些序列化的对象,我想理解为什么这实际上是必需的。毕竟,这是可以在启动/运行期间从数据库中恢复的信息。当然除了Token
之外,但我不明白为什么他们不只是存储 token (String
)而是存储对象。
最重要的:对这些类中的任何一个都进行最小的更改,并且它们不会反序列化!如果更改了其中一个类,则每个用户都将被迫重新登录,这完全违背了我首先要使用JdbcTokenStore
的原因-因此必定有一些可疑之处或我没有得到它
也许有人可以对此有所了解。
答案 0 :(得分:0)
看着你的咆哮,然后看你的代码,我也有些惊讶!它实际上是在将对象序列化(如您建议的那样),变成看起来非常不友好的对象字符串:
protected byte[] serializeAccessToken(OAuth2AccessToken token) {
return SerializationUtils.serialize(token);
}
似乎应该做什么(并且我不确定为什么他们没有在文档中指出这一点)是覆盖JdbcTokenStore
中的*serialize
方法:
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
并不感到惊讶,这对于Authentication
实现是正常的,而这正是Spring所做的方式。