如何处理 spring-security-oauth2 的版本升级?

Posted

技术标签:

【中文标题】如何处理 spring-security-oauth2 的版本升级?【英文标题】:How to handle version upgrades of spring-security-oauth2? 【发布时间】:2015-02-08 13:34:04 【问题描述】:

spring-security-oauth2 将 Authentication 对象保存为数据库中访问令牌条目的一部分,作为序列化的 java 对象 (ByteArrayOutputStream.writeObject(authentication))。

您如何处理 spring-security(可能会更改 SpringSecurityCoreVersion.SERIAL_VERSION_UID)和 spring-security-oauth(可能会更改 OAuth2Authentication 的 serialVersionUID)的版本升级?如果 serialVersionUID 发生变化,持久化的 Authentication 对象就不能再反序列化了。

我们得出的结论是,在升级框架版本时,删除包含序列化身份验证对象的访问令牌将是最干净、最简单的解决方案。任何想法如何更优雅地处理这个问题?

【问题讨论】:

据我所知,没有更好的迁移路径。访问令牌是短暂的 - 如果他们拥有的令牌无效,客户知道如何获取新令牌。 @DaveSyer,这可以通过不使用 Java 序列化并将这些对象序列化为 JSON 或使用 JPA 存储它们来解决吗?我看到序列化复杂的继承层次结构(如 org.springframework.security.core.Authentication 或 org.springframework.security.core.authority.Authority)会遇到困难,所以我想知道是否值得尝试实现这样的东西。 问题是您需要将所有可能的 Authentication 实现序列化为 JSON - 以及您无法控制的那些。使用 Jackson,您可以使用 mixins 来做到这一点,但是您使用的每个新的 Authentication 实现都需要一些工作。我们目前正在考虑使用Kryo 对其进行序列化。与普通的 Java 序列化相比,它对模型更改的弹性要大得多。 它对 Kryo 有效吗?在这里面临类似的问题:) 到目前为止,是的。但是您需要记住,Kryo 不能像 java 序列化那样开箱即用地序列化和反序列化 any 对象。因此,您需要一个适当的测试设置来确保测试所有所涉及的类的序列化和反序列化(如AuthenticationUserDetails 实现)。 【参考方案1】:

我认为最好的解决方案是将令牌扔掉。 SpringSecurityCoreVersion.SERIAL_VERSION_UID 的声明旁边有一条大评论:

/**
 * Global Serialization value for Spring Security classes.
 *
 * N.B. Classes are not intended to be serializable between different versions. See
 * SEC-1709 for why we still need a serial version.
 */

确实,他们故意在每个次要版本中(至少)撞到 SERIAL_VERSION_UID

(SEC-1709 的问题 cmets 解释了他们是如何得出这个解决方案的。)

我从 cmets 得到的是,如果您确实 尝试透明地处理版本升级,您可能 会导致事情中断,并产生不可预知的后果。 (这是可能的安全问题的“代码”。)


另一方面,OAuth2Authentication.serialVersionUID 在过去 9 年中似乎没有改变。

【讨论】:

以上是关于如何处理 spring-security-oauth2 的版本升级?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 UsernameNotFoundException 春季安全

如何处理c#中的错误代码

Akka 如何处理消息版本?

开玩笑测试 - 如何处理 JsonWebToken 响应

如何处理 JSON 响应

“不知道如何处理' nvcc 致命错误