使用PersistentTokenBasedRememberMeServices的Spring Security SessionRegistry

时间:2012-05-14 17:03:20

标签: spring-security

我的应用程序的sequrity系统基于Spring Sequrity 3.1。我正在使用PersistentTokenBasedRememberMeServices。

我需要使用Sessionregistrympl显示所有已记录用户的列表。问题是,当网站进入“rememberme-user”时,会话在SessionRegistry中不存在。

我的配置文件:web.xml

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

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

和spring-sequrity.xml:

<s:http auto-config="false" entry-point-ref="authenticationEntryPoint" > 

    <s:custom-filter position="FORM_LOGIN_FILTER" ref="authenticationFilter"/>
    <s:custom-filter position="REMEMBER_ME_FILTER" ref="rememberMeFilter" />
    <s:custom-filter position="CONCURRENT_SESSION_FILTER" ref= "concurrencyFilter" />           
    <s:custom-filter position="LOGOUT_FILTER" ref="logoutFilter" />

    <s:intercept-url pattern="/admin/**/" access="ROLE_ADMIN"/>     
    <s:intercept-url pattern="/**/" access="ROLE_USER, ROLE_GUEST"/>        
    <s:anonymous username="guest" granted-authority="ROLE_GUEST" />

</s:http>



<bean 
  id="logoutFilter"
  class="org.springframework.security.web.authentication.logout.LogoutFilter"
  p:filterProcessesUrl="/logout/">
  <constructor-arg value="/login/" />
    <constructor-arg>
    <list>
      <ref bean="rememberMeServices" />
      <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" p:invalidateHttpSession="true"/>
    </list>
    </constructor-arg>
</bean>


<bean id="authenticationEntryPoint"  
    class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"
    p:loginFormUrl="/login/"/>


<bean id="customAuthenticationSuccessHandler" 
    class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler"
    p:defaultTargetUrl="/index/" />


<bean id="customAuthenticationFailureHandler" 
    class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"
    p:defaultFailureUrl="/login/error/" />


<bean id="rememberMeServices" 
    class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices"
    p:tokenRepository-ref="jdbcTokenRepository"
    p:userDetailsService-ref="hibernateUserService"
    p:key="pokeristStore"
    p:tokenValiditySeconds="1209600" />

<bean id="jdbcTokenRepository" 
    class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl"
    p:dataSource-ref="dataSource"/>

<bean id="rememberMeAuthenticationProvider" class="org.springframework.security.authentication.RememberMeAuthenticationProvider"
    p:key="pokeristStore" />

<bean id="rememberMeFilter" 
    class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter"
    p:rememberMeServices-ref="rememberMeServices"
    p:authenticationManager-ref="authenticationManager" />


<bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"
    p:sessionAuthenticationStrategy-ref="sas"
    p:authenticationManager-ref="authenticationManager"
    p:authenticationFailureHandler-ref="customAuthenticationFailureHandler"
    p:rememberMeServices-ref="rememberMeServices"
    p:authenticationSuccessHandler-ref="customAuthenticationSuccessHandler"/>

<bean id="sas"      class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy"
    p:maximumSessions="1">
    <constructor-arg name="sessionRegistry" ref="sessionRegistry" />
</bean>

<bean id="concurrencyFilter" 
    class="org.springframework.security.web.session.ConcurrentSessionFilter"
    p:sessionRegistry-ref="sessionRegistry" />


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


<bean id="passwordEncoder"
    class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
    <constructor-arg value="256"/>
</bean>

<bean id="saltSource"  
    class="org.springframework.security.authentication.dao.ReflectionSaltSource">  
    <property name="userPropertyToUse" value="username"/>
</bean>

<bean id="hibernateUserService"
    class="com.mysite.service.simple.SecurityUserDetailsService"/>


<s:authentication-manager alias="authenticationManager">    
     <s:authentication-provider user-service-ref="hibernateUserService">            
        <s:password-encoder ref="passwordEncoder">
            <s:salt-source ref="saltSource"/>
        </s:password-encoder>   
    </s:authentication-provider>
    <s:authentication-provider ref="rememberMeAuthenticationProvider" />

我该如何解决这个问题?

我找到的解决方案之一 - 是在FilterSecurityInterceptor bean中将alwaysReauthenticate属性设置为'true',但它会影响网站的性能。

2 个答案:

答案 0 :(得分:2)

您需要ConcurrentSessionControlStrategy来填充会话注册表。本手册的session management部分对此进行了描述。如果要使用普通的Spring bean,请查看其中的配置示例。请注意,您需要将它注入到UsernamePasswordAuthenticationFiltersession-management命名空间元素的相同引用中。

答案 1 :(得分:0)

如果要填充SessionRegistry,Spring Security必须创建会话,尝试将create-session="always"添加到Spring Security配置文件中的<http>标记。