2016-04-26 55 views
0

我們使用spring安全性(org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy)來控制每個用戶允許登錄的次數。 下面是完整的配置:Spring安全ConcurrentSessionControlStrategy問題

核心安全的context.xml

<bean id="sessionRegistry" 
     class="org.springframework.security.core.session.SessionRegistryImpl" /> 

    <bean id="sessionStrategy" 
     class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy"> 
     <constructor-arg name="sessionRegistry" ref="sessionRegistry" /> 
     <property name="maximumSessions" 
      value="${core.web.config.sessionStrategy.maximumSessions.value}" /> 
     <property name="exceptionIfMaximumExceeded" value="true" /> 
    </bean> 

的web.xml

<listener> 
    <listener -class>org.springframework.security.web.session.HttpSessionEventPublisher 
     </listener-class> 
</listener> 

core.web.config.sessionStrategy.maximumSessions.value的值設爲根據我的理解,這意味着一個用戶可以有10個不同的登錄會話。當該用戶試圖同時在第11位登錄時,他不應該被允許。

但在我們的情況下,用戶能夠同時登錄成功5次,但是當我們試圖從第6位登陸,我們得到以下異常:

Authentication request failed: org.springframework.security.web.authentication.session.SessionAuthenticationException: ConcurrentSessionControlStrategy.exceededAllowed 

有沒有人遇到過類似的問題?調試很困難,因爲這只是在生產環境中發生的。 QA,UAT和其他環境正常工作。 Prod和其他環境之間的一個很大的區別是,在prod中有多個應用程序服務器(在我們的例子中是4個),QA和UAT只有1個服務器。這可能是原因還是別的。

在對此進行研究時,我注意到ConcurrentSessionControlStrategy類現在已被棄用。相反,它說使用ConcurrentSessionControlAuthenticationStrategy。任何想法爲什麼這個階級被剝奪?這可能是由於該班的錯誤嗎?

public class UserInfo implements org.springframework.security.core.userdetails.UserDetails { 

@Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     UserInfo other = (UserInfo) obj; 
     if (userEntityId == null) { 
      if (other.userEntityId != null) 
       return false; 
     } else if (!userEntityId.equals(other.userEntityId)) 
      return false; 
     return true; 
    } 

} 
+0

請注意,該控件位於經過身份驗證的用戶的「Principal」上。在Spring Security中,這是['UserDetails']的實現(http://docs.spring.io/spring-security/site/docs/3.1.7.RELEASE/apidocs/org/springframework/security/core/userdetails/ UserDetails.html)你正在使用。如果您使用自定義的'UserDetails'(也許是一個自定義的'UserDetailsS​​ervice'),那麼它的'equals'方法就非常重要。 –

+0

感謝@BoristheSpider的評論。是的,我們使用自定義的UserDetailsS​​ervice:「公共類UserDetailService實現org.springframework.security.core.userdetails.UserDetailsS​​ervice」。這個類只有一個方法 - loadUserByUsername(String userName),其中我們根據userName從數據庫獲取userInfo對象。這個類沒有重寫equals方法。你是否暗示我們需要重寫UserDetailsS​​erviceImpl類中的equals方法? – user1270392

+0

不在_service_上,而是在從服務返回的bean上。這是['UserDetails']的自定義實現(http://docs.spring.io/autorepo/docs/spring-security/3.2.2.RELEASE/apidocs/org/springframework/security/core/userdetails/UserDetails。 HTML)? –

回答

0

您是否可以在產品環境中確認core.web.config.sessionStrategy.maximumSessions.value的屬性值? Prod和其他環境可能不同。

+0

謝謝。是的,我們對這些價值進行了驗證,他們在產品和非產品環境中都應該是這樣。關於我對「多服務器」的評論有什麼想法?不知道在整個羣集環境中整個事情會如何工作。 – user1270392

+0

是否爲粘性會話配置了prod環境?您是使用Spring Session將會話集中到外部存儲還是僅使用基礎服務器會話存儲? –

+0

此外,請確保您的配置按照[參考文檔](http://docs.spring.io/spring-security/site/docs/3.2.9.RELEASE/reference/htmlsingle/#concurrent-sessions)進行設置。您當前的配置「core-security-context.xml」可能缺少一些核心組件。 –