我們使用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;
}
}
請注意,該控件位於經過身份驗證的用戶的「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'(也許是一個自定義的'UserDetailsService'),那麼它的'equals'方法就非常重要。 –
感謝@BoristheSpider的評論。是的,我們使用自定義的UserDetailsService:「公共類UserDetailService實現org.springframework.security.core.userdetails.UserDetailsService」。這個類只有一個方法 - loadUserByUsername(String userName),其中我們根據userName從數據庫獲取userInfo對象。這個類沒有重寫equals方法。你是否暗示我們需要重寫UserDetailsServiceImpl類中的equals方法? – user1270392
不在_service_上,而是在從服務返回的bean上。這是['UserDetails']的自定義實現(http://docs.spring.io/autorepo/docs/spring-security/3.2.2.RELEASE/apidocs/org/springframework/security/core/userdetails/UserDetails。 HTML)? –