因此用户登录 - > 关闭浏览器 - > 再次打开浏览器 - > 错误:
HTTP Status 401 - Authentication Failed: Maximum sessions of 1 for this principal exceeded
我需要的是捕获会话无效的事件,删除该用户的所有会话并重定向到正常登录页面
spring security config:
<http auto-config="true" use-expressions="true">
<session-management session-fixation-protection="migrateSession">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
</session-management>
<intercept-url pattern="/login" access="hasRole('ROLE_ANONYMOUS')" requires-channel="any"/>
<!--<custom-filter after="CONCURRENT_SESSION_FILTER" ref="sessionExpiration" /> -->
<!-- .... -->
</http>
<beans:bean id="sessionExpiration" class="com.test.security.SessionExpirationFilter">
<beans:property name="expiredUrl">
<beans:value>/login</beans:value>
</beans:property>
</beans:bean>
我试图实现一些过滤器,但它总是显示会话为空:
public class SessionExpirationFilter implements Filter, InitializingBean {
private String expiredUrl;
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String path = httpRequest.getServletPath();
HttpSession session = httpRequest.getSession(false);
System.out.println(session);
if (session == null && !httpRequest.isRequestedSessionIdValid()) {
SecurityContextHolder.getContext().setAuthentication(null);
String targetUrl = httpRequest.getContextPath()
+ expiredUrl;
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(targetUrl));
return;
}
chain.doFilter(request, response);
}
public void setExpiredUrl(String expiredUrl) {
this.expiredUrl = expiredUrl;
}
}
答案 0 :(得分:6)
根据我的理解,如果用户的会话超过“max-sessions”,您希望使之前的会话无效。将属性'error-if-maximum-exceeded'设置为false。 Spring安全性会自动使上一个会话无效。
如果你想尝试不同的事情,
答案 1 :(得分:2)
设置error-if-maximum-exceeded="false"
将允许第二个会话并使第一个会话无效max-sessions="1"
如果您有max-sessions="2"
,那么它也会允许Nth
会话并使所有N-2
次会话无效
<session-management session-fixation-protection="migrateSession">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="false"/>
</session-management>
设置error-if-maximum-exceeded="true"
将NOT
允许第二个会话,并使第二个会话无效为max-sessions="1"
如果您有max-sessions="2"
,那么它将不允许2+
个会话并且无效。
答案 2 :(得分:0)
基于以上答案
Spring安全性会自动使上一个会话无效
如果要在登录页面上重定向用户,可以添加
<session-management invalid-session-url="/login.html">
...
</session-management>
由于上一个会话已经无效。
我在上面的评论中也已经读到,当您尝试再次登录时,您可能希望保留上一个会话。但这仍然打败了您的第一个问题。
您在谈论7. Session Fixation Protection with Spring Security
该框架提供了针对典型会话修复的保护 通过配置现有会话发生什么情况来进行攻击 用户尝试再次进行身份验证:
<session-management session-fixation-protection="migrateSession">
相应的Java配置:
http.sessionManagement().sessionFixation().migrateSession()
默认情况下,Spring Security启用了此保护 (“ migrateSession”)–进行身份验证后,将创建一个新的HTTP会话, 旧会话无效,旧会话的属性为 复制过来。
如果这不是所需的行为,则可以使用其他两个选项:
设置
“none”
时,原始会话不会无效设置
“newSession”
时,将创建一个干净的会话,而没有任何 从旧会话复制过来的属性
答案 3 :(得分:-1)
<session-management session-authentication-strategy-ref="sas"/>
<beans:bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:property name="maximumSessions" value="1"/>
<beans:property name="exceptionIfMaximumExceeded" value="true"/>
<beans:constructor-arg name="sessionRegistry" ref="sessionRegistry"/>
</beans:bean>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/>
&#13;