注销后会话似乎保持活动状态。我使用的是Spring 5,我将我的安全配置定义为:
<session-management invalid-session-url="/invalid-session" session-fixation-protection="none">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true"
expired-url="/expired-session" session-registry-alias="sessionRegistry"/>
</session-management>
<logout logout-url="/logout"
delete-cookies="JSESSIONID"
logout-success-url="/index"
invalidate-session="true"/>
我的应用程序中的注销按钮是针对 /logout的,它看起来工作正常。在我的控制器中返回活动会话的逻辑是:
sessionRegistry.getAllPrincipals().stream()
.filter(p -> p instanceof PrincipalImpl)
.filter(p -> !sessionRegistry.getAllSessions(p, false).isEmpty())
.map(Object::toString)
.collect(Collectors.toList());
因此,即使在许多天之后,会话在注销后似乎仍然处于活动状态。
我花了很多天和几周的时间试图解决这个问题,阅读不同类型的Spring Security教程。
似乎您的会话管理和注销配置是正确的。一个可能的原因是用户注销时会话注册表没有正确更新。
确保您的配置中有一个SessionRegister stryImpl bean:
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
在您的安全配置中扩展WebSecurityConfigrerAdapter类并覆盖configure(HttpSecurity超文本传输协议)方法:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SessionRegistry sessionRegistry;
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionFixation().none()
.maximumSessions(1)
.sessionRegistry(sessionRegistry)
.expiredUrl("/expired-session")
.and()
.invalidSessionUrl("/invalid-session")
.and()
.logout()
.logoutUrl("/logout")
.deleteCookies("JSESSIONID")
.logoutSuccessUrl("/index")
.invalidateHttpSession(true)
// Other configurations, e.g., authentication and authorization
;
}
}
实现自定义LogoutRestessHandler以从SessionRegister中显式删除会话:
@Component
public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
@Autowired
private SessionRegistry sessionRegistry;
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response