java - 过期 session 出现 NullPointerException

标签 java spring security session model-view-controller

我正在使用 Spring,当我更新用户时,我需要使用户的 session 过期。我正在使用以下配置:

@Bean
@Override
public AuthenticationManager authenticationManagerBean () throws Exception {

    return super.authenticationManagerBean();

}

@Bean
public SessionRegistry sessionRegistry () {

    return new SessionRegistryImpl();

}
@Bean
public ServletListenerRegistrationBean httpSessionEventPublisher() {    //(5)
    return new ServletListenerRegistrationBean(new HttpSessionEventPublisher());
}

@Override
public void configure(AuthenticationManagerBuilder authenticationMgr) throws Exception {

    authenticationMgr.userDetailsService(inMemoryUserDetailsManager());

}

@Override
protected void configure (HttpSecurity http) throws Exception {

    http.authorizeRequests()
        .antMatchers("*.jsp").authenticated()
        .and()
            .formLogin().loginPage("/login.html")
            .defaultSuccessUrl("/")
            .failureUrl("/login.html?failed=1")
            .usernameParameter("email").passwordParameter("password")               
        .and()
            .logout().logoutUrl("/logout.html")
        .and()
            .logout().logoutSuccessUrl("/")
        .and()
            .sessionManagement()
            .maximumSessions(100)
            .maxSessionsPreventsLogin(true)
            .expiredUrl("/ejercicios-programacion/")
            .sessionRegistry(sessionRegistry());

}

这就是我终止 session 的方式:

public void expireUserSessions(String username) {
    for (Object principal : sessionRegistry.getAllPrincipals()) {
        if (principal instanceof User) {
            UserDetails userDetails = (UserDetails) principal;
            if (userDetails.getUsername().equals(username)) {
                for (SessionInformation information : sessionRegistry.getAllSessions(userDetails, false)) {
                    information.expireNow();
                }
            }
        }
    }
}

完成此操作后,我在更新用户的浏览器上重新加载页面,它将显示异常:

java.lang.NullPointerException
org.springframework.security.web.session.ConcurrentSessionFilter$1.onExpiredSessionDetected(ConcurrentSessionFilter.java:107)

重定向到:

@Override
public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException {
    HttpServletRequest request = event.getRequest();
    HttpServletResponse response = event.getResponse();
    SessionInformation info = event.getSessionInformation();

    redirectStrategy.sendRedirect(request, response, determineExpiredUrl(request, info));
}

特别是,它是抛出异常的最后一行代码。如果我在收到异常后再次重新加载页面,那么一切都很好;我没有遇到任何异常,并且我已注销。我不知道为什么会发生这种情况。有人知道吗?

最佳答案

好吧,我终于解决了这个问题。答案是使用您自己的 ConcurrentSessionFilter,因为默认方法使用的许多方法已被弃用。添加此 bean:

 @Bean public ConcurrentSessionFilter concurrentSessionFilter() {

    ConcurrentSessionFilter c = new ConcurrentSessionFilter(sessionRegistry(), new SessionInformationExpiredStrategy() {

        @Override
        public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException {

            HttpServletRequest request = event.getRequest();
            HttpServletResponse response = event.getResponse();
            SessionInformation info = event.getSessionInformation();

            redirectStrategy().sendRedirect(request, response, "/ejercicios-programacion/");

        }
    });

    return c;

}

并在覆盖的方法中执行您想要的任何操作,在我的例子中,我使用新的 RedirectStrategy 将用户移动到索引页。

然后将其添加到您的配置方法中:

protected void configure (HttpSecurity http) throws Exception {

    ...
    // Whatever you want to configure

    http.addFilterBefore(concurrentSessionFilter(), ConcurrentSessionFilter.class);

}

我不敢相信这是多么不直观,我不知道像过期 session 这样简单的事情在 Spring 中怎么会如此困难和迟钝

关于java - 过期 session 出现 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57100851/

相关文章:

java - 查找不相交集的数量

java - 如何在JFrame中排列,升序,降序,冒泡,输入区域,输出区域

java - Spring 3拦截器错误: Type Element type "beans" must be followed by either attribute specifications, ">"或 "/>"

json - spring MockMVC 中是否有一种方法可以将 json 内容作为对象获取?

security - 对CBC和ECB使用相同的AES key

java - 调用抛出异常的方法

java - 另一个数组中的数组有什么缺点?

spring - Spring 事务是否通过新实例传播

security - 使用另一台服务器存储文件: Good or bad idea?

linux - 使用端口 80 (Ubuntu/Linode) 运行 Node.js 时的最佳实践