代码之家  ›  专栏  ›  技术社区  ›  Griff

无法使Spring3会话并发控制工作

  •  3
  • Griff  · 技术社区  · 14 年前

    使用SpringSecurity3.1.0,我似乎无法使并发会话控制功能正常工作。当我同时使用IE和火狐(使用本地工作站)登录系统时,我在会话注册表中看到了两次我的用户原则。我希望并发会话控件将我注销或引发异常,或者执行一些指示我已多次登录到该站点的操作,但这是不允许的。

    就其价值而言,即使指定我的站点使用自定义登录表单,我也无法使用HTTP命名空间元素的自动配置让并发控制完全正常工作。我想知道这是否是因为我的身份验证是通过LDAP提供的…?

    这是我的安全配置。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/security"
     xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
               http://www.springframework.org/schema/security
               http://www.springframework.org/schema/security/spring-security-3.0.xsd">
    
     <http auto-config="false" use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint">
         <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
         <custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter"/>
         <session-management session-authentication-strategy-ref="sas"/>
      <intercept-url pattern="/" access="permitAll" />
      <intercept-url pattern="/css/**" access="permitAll" />
      <intercept-url pattern="/images/**" access="permitAll" />
      <intercept-url pattern="/js/**" access="permitAll" />
      <intercept-url pattern="/public/**" access="permitAll" />
      <intercept-url pattern="/home/**" access="permitAll" />
      <intercept-url pattern="/admin/user/**" access="hasRole('AUTH_MANAGE_USERS')" />
      <intercept-url pattern="/admin/group/**" access="hasRole('AUTH_MANAGE_USERS')" />
      <intercept-url pattern="/**" access="isAuthenticated()" />
      <access-denied-handler error-page="/403.html"/>
      <logout invalidate-session="true" logout-success-url="/public/home.do"/>
     </http>
    
        <beans:bean id="authenticationProcessingFilterEntryPoint"
              class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
            <beans:property name="loginFormUrl" value="/public/login.do"/>
            <beans:property name="forceHttps" value="false"/>
        </beans:bean>
    
      <beans:bean id="concurrencyFilter"
           class="org.springframework.security.web.session.ConcurrentSessionFilter">
         <beans:property name="sessionRegistry" ref="sessionRegistry" />
         <beans:property name="expiredUrl" value="/expired.html" />
       </beans:bean>
    
       <beans:bean id="myAuthFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
         <beans:property name="sessionAuthenticationStrategy" ref="sas" />
         <beans:property name="authenticationManager" ref="authenticationManager" />
       </beans:bean>
    
       <beans:bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
         <beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
         <beans:property name="maximumSessions" value="1" />
         <beans:property name="exceptionIfMaximumExceeded" value="true"/>
       </beans:bean>
    
     <authentication-manager alias="authenticationManager">
      <authentication-provider ref='ldapProvider' />
      <authentication-provider ref="externalUserLdapProvider"/>
     </authentication-manager>
    
     <beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
    
     <beans:bean id="securityContext" 
      class="org.springframework.security.core.context.SecurityContextHolder" factory-method="getContext"/>
    
     <beans:bean id="ldapProvider"
      class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
      <beans:constructor-arg ref="bindAuthenticator" />
      <beans:constructor-arg ref="userService" />
      <beans:property name="userDetailsContextMapper" ref="permissionedUserContextMapper" />
     </beans:bean>
    
     <beans:bean id="permissionedUserContextMapper"
      class="...service.impl.PermissionedUserContextMapperImpl" >
      <beans:property name="userDao" ref="userDao"/>
     </beans:bean>  
    
     <!-- LDAP via AD-->
     <beans:bean id="bindAuthenticator"
      class="org.springframework.security.ldap.authentication.BindAuthenticator">
      <beans:constructor-arg ref="contextSource" />
      <beans:property name="userSearch" ref="userSearch" />
     </beans:bean>
    
     <beans:bean id="userSearch"
      class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
      <beans:constructor-arg>
       <beans:value></beans:value>
      </beans:constructor-arg>
      <beans:constructor-arg>
       <beans:value>(sAMAccountName={0})</beans:value>
      </beans:constructor-arg>
      <beans:constructor-arg ref="contextSource" />
      <beans:property name="searchSubtree">
       <beans:value>true</beans:value>
      </beans:property>
     </beans:bean>
    
     <beans:bean id="contextSource"
      class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
      <beans:constructor-arg
       value="ldap://omitted" />
      <beans:property name="userDn"
       value="ommitted" />
      <beans:property name="password" value="omitted" />
     </beans:bean>
    
     <!--  Second LDAP Authenticator (Apache DS) -->
        <beans:bean id="externalUserLdapProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
            <beans:constructor-arg ref="externalUserBindAuthenticator"/>
      <beans:constructor-arg ref="userService" />
      <beans:property name="userDetailsContextMapper" ref="permissionedUserContextMapper" />
        </beans:bean>
    
     <beans:bean id="externalUserBindAuthenticator" class="org.springframework.security.ldap.authentication.BindAuthenticator">
      <beans:constructor-arg ref="externalUserContextSource" />
      <beans:property name="userDnPatterns">
       <beans:list>
        <beans:value>cn={0},ou=Users</beans:value>
       </beans:list>
      </beans:property>
     </beans:bean>
    
     <beans:bean id="externalUserContextSource" 
       class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
         <beans:constructor-arg value="ldap://omitted"/>
     </beans:bean>
    
    </beans:beans>
    

    如果用户登录超过1个会话,我是否缺少一些应该将并发控制策略告知BARF的属性?我知道同一个用户记录了不止一个会话——正如我在会话注册表中看到的一样。

    任何/所有回复都非常感谢!事先谢谢!

    1 回复  |  直到 14 年前
        1
  •  5
  •   axtavt    14 年前

    SessionRegistry 使用 equals() / hashCode() 属于 UserDetails 查找同一用户的会话。如果你有习惯 用户详细信息 可能还没有实现。

    推荐文章