【问题标题】:NullPointerException on expired session过期会话上的 NullPointerException
【发布时间】:2019-11-27 18:19:08
【问题描述】:

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

@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());

}

这就是我过期会话的方式:

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));
}

特别是,最后一行代码引发了异常。如果我在收到异常后再次重新加载页面,那么一切都很好;我没有例外,我已注销。我不知道为什么会这样。有人知道吗?

【问题讨论】:

  • 您是否尝试在第一次方法调用时调试并检查redirectStrategy 是否为空?
  • 谢谢。刚查了一下,redirectStrategy 为空,请问如何解决?
  • 我不确定。当您第一次启动它时,听起来它不在春季环境中。你能在你的new RedirectStrategyDefault () 行放一个断点,看看是否到达?
  • 这很奇怪,我不确定发生了什么。不幸的是我今天必须离开,我希望其他人可以帮助!
  • 不用担心,感谢您的帮助!

标签: java spring security session model-view-controller


【解决方案1】:

好的,我终于设法解决了这个问题。答案是使用您自己的 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);

}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    • 2016-08-04
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多