如何修复java.io.InvalidClassException:org.springframework.security.core.context.SecurityContextImpl

问题描述 投票:0回答:3

我最近升级了我的 Spring Boot 应用程序的 Spring,结果底层 Spring Security Core 升级到了 5.4.5。

现在启动 Spring Boot 应用程序时,我看到以下问题:

org.eclipse.jetty.server.HttpChannel - handleException / java.io.InvalidClassException: 
org.springframework.security.core.context.SecurityContextImpl; local class incompatible: 
stream classdesc serialVersionUID = 530, local class serialVersionUID = 540

在这种情况下,我在 GitHub 上找到了这篇文章:https://github.com/spring-projects/spring-security/issues/9204https://github.com/spring-projects/spring-security /问题/3736.

但我不知道如何解决这个问题。有人可以帮忙吗?谢谢。

java spring spring-boot spring-security
3个回答
4
投票

https://github.com/spring-projects/spring-security/issues/9204你可以找到: “Spring Security 无意在版本之间进行序列化”

这真是令人兴奋。所以版本升级时所有用户都需要注销!?

你能做什么?对于当前的升级,您必须注销所有用户。但您可以为下一次升级做好准备:

您需要为会话对象编写自己的序列化。这是一个项目,他们添加了自己的会话序列化用户 Jackson 和一些 Redis 库。例如,即使您使用 mysql,此代码也无需更改即可工作:

https://raw.githubusercontent.com/klboke/apollo/091a757d0a3c2173d6c600cd6a9a1595bb73c10c/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/config/SpringSessionConfig.java

有一点需要注意。因此,如果您不在生产中,那么您添加此配置,当安全库升级时,您就可以了,但是如果您在生产中第一次部署此配置,则所有用户都需要首先注销,因为会话的序列化不会适合上一个!


0
投票

转换器或会话存储库并不能涵盖所有会话失败。 因此我做了一个 hack,在特定路径上我们终止浏览器端的会话(因为服务器端 jdbc/redis 会话负载无法恢复)。在我的项目中,如果出现不可恢复的错误,FE 注销屏幕可用。

@Slf4j
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RecoverSessionFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        try {
            chain.doFilter(servletRequest, servletResponse);
        } catch (Exception e) {
            if (((HttpServletRequest) servletRequest).getServletPath().endsWith("/logout")) {
                Cookie cookie = new Cookie("SESSION", null);
                cookie.setPath("/");
                cookie.setHttpOnly(true);
                cookie.setMaxAge(0);
                ((HttpServletResponse) servletResponse).addCookie(cookie);
            }
            throw e;
        }
    }
}

0
投票

版本从3.1.3更新至3.3.4。 显然,这是因为 Spring Security 的问题。 因为这是一个开发项目,所以我只是删除了整个开发数据库并重新创建了它。 我认为问题是由数据库中两个 Spring 会话表中存储的数据引起的(因为 Spring Security 将数据存储在会话上,并且由于 Spring Security 更新和版本之间生成的某些数据值结构不兼容而导致一些数据问题)。

** 解决方案:所以我认为一种可行的解决方案可能是删除存储在数据库会话表中的应用程序的所有会话数据(显然,如果您将会话数据存储在数据库中)。

您可以在网上找到这个使我得出此行为结论的英特尔,也感谢之前发布的用户回答:SecurityContext 主要代表持久会话。它包含一个身份验证,该身份验证在 Web 应用程序的上下文中封装了经过身份验证的用户的信息。 SecurityContextRepository 的默认实现将 SecurityContext 存储在 HttpSession 中。

© www.soinside.com 2019 - 2024. All rights reserved.