2016-04-26 50 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”可能缺少一些核心组件。 –