超过此主体的最大会话时的Spring安全重定向

Ser*_*gey 1 java spring spring-security

所以用户登录- >关闭浏览器- >再次打开浏览器- >出现错误:

HTTP Status 401 - Authentication Failed: Maximum sessions of 1 for this principal exceeded
Run Code Online (Sandbox Code Playgroud)

我需要的是捕获会话无效的事件,删除该用户的所有会话并重定向到正常登录页面

spring security配置:

        <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>
Run Code Online (Sandbox Code Playgroud)

我试图实现一些过滤器,但它总是显示会话为空:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Adi*_*Adi 6

根据我的理解,如果用户的会话超过"max-sessions",您希望使之前的会话无效.将属性'error-if-maximum-exceeded'设置为false.Spring安全性会自动使上一个会话无效.

如果你想做一些与众不同的事,

  1. 扩展ConcurrentSessionControlStrategy类,并覆盖'allowableSessionsExceeded'方法.
  2. 将上面的bean引用指定为'session-management'的'session-authentication-strategy-ref'属性值

.