1

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

HTTP Status 401 - Authentication Failed: Maximum sessions of 1 for this principal exceeded

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

弹簧安全配置:

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

4 回答 4

6

据我了解,如果用户的会话超过“最大会话”,则您希望使上一个会话无效。将属性 'error-if-maximum-exceeded' 设置为 false。Spring 安全性自动使先前的会话无效。

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

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

.

于 2013-02-21T21:16:20.710 回答
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+会话并使其无效。

于 2016-09-28T07:13:07.123 回答
0
于 2018-09-28T14:28:57.890 回答
-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"/>

于 2017-04-04T15:34:08.217 回答