Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 为什么我的JdbcTokenStore会序列化Java对象?_Spring_Spring Boot_Spring Security_Spring Oauth2 - Fatal编程技术网

Spring 为什么我的JdbcTokenStore会序列化Java对象?

Spring 为什么我的JdbcTokenStore会序列化Java对象?,spring,spring-boot,spring-security,spring-oauth2,Spring,Spring Boot,Spring Security,Spring Oauth2,所以我只是从MemoryTokenStore中的移动到JdbcTokenStore。像往常一样,一个看似简单的改变之后,伴随着一些副作用,包括吞咽的例外——抱歉,这是一个咆哮 这是我用来访问用户主体的方式: Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String username = (String) authentication.getPrincipal();

所以我只是从MemoryTokenStore中的
移动到
JdbcTokenStore
。像往常一样,一个看似简单的改变之后,伴随着一些副作用,包括吞咽的例外——抱歉,这是一个咆哮

这是我用来访问用户主体的方式:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = (String) authentication.getPrincipal();

弗斯特 出于某种原因,
getPrincipal()
总是只返回用户名,而不是
UserDetails
对象。这对我来说已经足够好了,所以我选择了它

现在我更改了令牌存储,
getPrincipal()
确实返回了
UserDetails
对象。我可以接受这一点,但我想知道为什么这一点突然发生了变化——我不得不重构一些代码,因为我一直希望用户名是从
getPrincipal()
到现在为止。我也想知道我是否可以改变这一点

第二 据我所见,
JdbcTokenStore
似乎序列化了Java对象。它尝试序列化
标记
对象和
用户详细信息
对象。列
token
authentication
似乎代表了那些序列化对象,我想理解为什么这实际上是必要的。毕竟,这些信息可以在启动/运行时从数据库中恢复。当然除了
标记
,但我不明白为什么他们不存储标记(字符串
),而是存储对象

最重要的是:对这些类中的任何一个进行最轻微的更改,它们都不会被反序列化!如果其中一个类发生更改,每个用户都将被迫重新登录,这与我想首先使用
JdbcTokenStore
的原因不符,因此一定有可疑之处,或者我没有得到它



也许有人能对此有更多的了解。

看着你的咆哮,然后再看看你的代码,我也有点惊讶!它在幕后所做的实际上是将对象(如您所建议的!)序列化为一个看起来非常不友好的对象字符串:

protected byte[] serializeAccessToken(OAuth2AccessToken token) {
    return SerializationUtils.serialize(token);
}
看起来我们应该做的(我不确定他们为什么没有在文档中指出这一点)是覆盖以下文件中的
*serialize
方法:

这可能就是他们都受到保护的原因。实施可能如下所示:

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就是这样做的。

Hmm。。覆盖默认实现不是我想做的事情,但这是一个好主意。然而,我认为这可能会使很多事情复杂化,因为当我反序列化(用户名)时,我必须从这个对象创建一个
OAuth2Authentication
对象,我想,这将需要额外的代码。我不确定是否可以这样做,但我会尝试。啊,我也必须改变行为
getPrincipal()
还必须只返回用户名..好的,我可能看到了这里的困难,也可能是
OAuth2Authentication
oauth\u access\u token
表的
authentication
列序列化的原因。此对象还包含一个
OAuth2Request
对象,该对象似乎包含有关用户身份验证的一些基本信息。我相信这是他们这么做的主要原因。我不得不说这很奇怪——主要是因为“如果我更改了UserDetails类会发生什么?”。因此,我认为要解决所有这些问题,我认为有可能..让
getPrincipal()
只返回用户名。这样一来,
OAuth2Authentication
不会保存例如
MyUserDetailsImpl
,而只是一个
字符串。现在,只有对
OAuth2Authentication
类中的任何内容进行更改(我猜),事情才会破裂^^我不必担心他们的变化。如果他们是这样做的,他们很可能会考虑到向后兼容性。如果您担心他们不会这样做(可能!),您可以使用此序列化解决方案,将其与Spring版本一起进行版本设置,并在进行反序列化时将其作为提示
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...

}