2

我的应用程序的 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”,但这会影响网站的性能。

4

2 回答 2

2

您需要一个ConcurrentSessionControlStrategy, 来填充会话注册表。这在手册的会话管理部分中进行了描述。如果您想使用普通的 Spring bean,请查看其中的配置示例。请注意,您需要将它注入到两者中,以提供对 theUsernamePasswordAuthenticationFiltersession-managementnamespace 元素的相同引用。

于 2012-05-15T16:57:40.303 回答
0

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

于 2012-05-15T11:45:10.423 回答