我们使用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)? –