2013-02-21 75 views
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; 
    } 
} 

回答

6

从我的理解,要前一交易日无效,如果用户的会话超过“最大的会话” 。将属性'error-if-maximum-exceeded'设置为false。 Spring安全会自动使以前的会话失效。

如果你正在尝试做不同的事情,

  1. 扩展ConcurrentSessionControlStrategy类,并覆盖 'allowableSessionsExceeded' 的方法。
  2. 指定上述的bean引用为 '会话管理'

的 '会话的认证策略-REF' 属性值。

+0

我已经设置'错误如果利用最大exceeded'为'FALSE'。当我尝试多次登录时,最新的会话将会使以前的会话失效。但是,*如果我必须保持第一次会话,并且不允许在第一次登出完成之前再次登录,该怎么办?*您是否知道如何实现这一点? – OO7 2015-05-14 09:19:55

+0

@ OO7您需要将该属性设置为'true',那么第二个会话将不被允许 'error-if-maximum-exceeded =“true”' – 2016-09-28 07:06:33

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+会话和无效。

-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"/>

+1

欢迎使用Stack Overflow!虽然这可能会在理论上回答这个问题,[这将是更可取的](// meta.stackoverflow.com/q/8259)在这里包括答案的基本部分,并提供参考链接。 – 2017-04-04 15:52:09