Java 已过期会话上的NullPointerException
我正在使用Spring,当我更新某个用户时,我需要终止该用户的会话。我正在使用以下配置:Java 已过期会话上的NullPointerException,java,spring,security,session,model-view-controller,Java,Spring,Security,Session,Model View Controller,我正在使用Spring,当我更新某个用户时,我需要终止该用户的会话。我正在使用以下配置: @Bean @Override public AuthenticationManager authenticationManagerBean () throws Exception { return super.authenticationManagerBean(); } @Bean public SessionRegistry sessionRegistry () { return
@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));
}
特别是,它是引发异常的最后一行代码。如果在获得异常后再次重新加载页面,则一切正常;我没有例外,我已经注销了。我不知道为什么会这样。有人知道吗?好的,我终于解决了这个问题。答案是使用您自己的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;
}
在Overwrited方法中,你想做什么就做什么,在我的例子中,我使用了新的重定向策略将用户移动到索引页面
然后将其添加到配置方法中:
protected void configure (HttpSecurity http) throws Exception {
...
// Whatever you want to configure
http.addFilterBefore(concurrentSessionFilter(), ConcurrentSessionFilter.class);
}
我真不敢相信这是多么的不直观,我不知道在春季,会话过期这样简单的事情怎么会如此困难和迟钝您是否尝试过调试并检查
重定向策略
在第一次方法调用时是否为空?谢谢。刚刚检查过,重定向策略为空,我如何修复它?我不确定。听起来,当您第一次启动它时,它不在spring上下文中。你能在新的RedirectStrategyDefault()
行上设置一个断点,看看是否达到了它吗?这很奇怪,我不确定到底发生了什么。不幸的是,我今天要走了,我希望其他人能帮助我!不用担心,谢谢你的帮助!