春季安全会话注册表为空

Posted

技术标签:

【中文标题】春季安全会话注册表为空【英文标题】:spring security session registry empty 【发布时间】:2014-02-20 18:36:57 【问题描述】:

我有一个使用 spring security 的 spring mvc webapp,每次用户登录时我想做的一件事就是记录系统上的并发用户数。

为此,我给我的会话注册表一个别名,然后我自动连接到一个类并说...

List<Object> principals = sessionRegistry.getAllPrincipals();
MDC.put(MDCKeyConstants.CONCURRENT_USER_COUNT, principals.size());

但 principals.size 即将变为 0 。即主体列表为空。我是否缺少需要配置的其他内容?

抱歉,这篇文章很长,但我将我的 spring 安全配置放在这里,以尝试在此问题上获得一些帮助。在此先感谢...

<http use-expressions="true" auto-config="false" entry-point-ref="loginUrlAuthenticationEntryPoint">    
    <!-- custom filters -->
    <custom-filter position="FORM_LOGIN_FILTER" ref="twoFactorAuthenticationFilter" />      
    <custom-filter after="SECURITY_CONTEXT_FILTER" ref="securityLoggingFilter"/>

    <!-- session management -->     
    <session-management 
        invalid-session-url="/sessionExpired.htm" 
        session-authentication-error-url="/alreadyLoggedIn.htm">

        <concurrency-control 
            max-sessions="1" 
            expired-url="/sessionExpiredDuplicateLogin.htm" 
            error-if-maximum-exceeded="false" 
            session-registry-alias="sessionRegistry"/>

    </session-management>   

    <!-- error handlers -->
    <access-denied-handler error-page="/accessDenied.htm"/>             

    <!-- logout --> 
    <logout logout-success-url="/logout.htm" invalidate-session="false" delete-cookies="JSESSIONID"/>   

    <!-- authorize pages -->    
    <intercept-url pattern="/home.htm" access="isAuthenticated()" />
    <intercept-url pattern="/shortsAndOvers.htm" access="isAuthenticated()" />
    <intercept-url pattern="/shortsAndOversDaily.htm" access="isAuthenticated()" />
    <intercept-url pattern="/birtpage.htm" access="isAuthenticated()" />
    <intercept-url pattern="/reports/show.htm" access="isAuthenticated()" />    

</http> 

<!-- =============================== -->
<!--      AUTHENTICATION BEANS       -->
<!-- =============================== -->

<beans:bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
  <beans:property name="userDetailsService" ref="userDetailsDao" />
  <beans:property name="passwordEncoder" ref="encoder" />
</beans:bean>

<beans:bean id="twoFactorAuthenticationFilter" class="com.mycompany.reporting.security.TwoFactorAuthenticationFilter">
    <beans:property name="authenticationManager" ref="authenticationManager" />
    <beans:property name="authenticationFailureHandler" ref="failureHandler" />
    <beans:property name="authenticationSuccessHandler" ref="successHandler" />        
    <beans:property name="filterProcessesUrl" value="/j_spring_security_check" />
    <beans:property name="postOnly" value="true" />
</beans:bean>

<beans:bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <beans:property name="loginFormUrl" value="/login.htm" />
</beans:bean>

<beans:bean id="successHandler" class="com.mycompany.reporting.security.CustomSavedRequestAwareAuthenticationSuccessHandler">
    <beans:property name="defaultTargetUrl" value="/home.htm" />
</beans:bean>

<beans:bean id="failureHandler" class="com.mycompany.reporting.security.CustomSimpleUrlAuthenticationFailureHandler">
    <beans:property name="defaultFailureUrl" value="/loginfailed.htm" />
</beans:bean>                          

<authentication-manager alias="authenticationManager">
    <authentication-provider ref="authenticationProvider"></authentication-provider>
</authentication-manager>

【问题讨论】:

你有没有在你的 web.xml 中提到过 springsecurity 的 HttpSessionEventPublisher 监听器 是的,我有。 org.springframework.security.web.session.HttpSessionEventPublisher 尝试在 spring-security.xml 中提及 @Richie 嗨,我也遇到了同样的问题,找到解决方案了吗? 嗨@rishiAgar。我接受了下面的答案,因为它是正确的。 S抱歉耽搁了。 【参考方案1】:

试试这个。它对我有用。

&lt;http&gt;&lt;/http&gt;

&lt;session-management session-authentication-strategy-ref="sas" invalid-session-url="/invalid-session" /&gt;

并声明bean如下:

&lt;beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/&gt;

<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:bean>

不要忘记将 org.springframework.security.web.session.HttpSessionEventPublisher 监听器添加到您的 Web 配置中。

【讨论】:

感谢哈迪克。实际上,我前段时间就找到了这个答案,但我可以确认您指定的是我解决此问题的确切方法。 类名可能已更改为 org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy 如果您使用自定义身份验证,那么它不会开箱即用,必须进行一些配置。参考这个***.com/a/65542389/9004116

以上是关于春季安全会话注册表为空的主要内容,如果未能解决你的问题,请参考以下文章

如何在身份验证之后和注销之前调用方法? (春季安全)

春季安全会话到期

春季安全会话超时

春季安全会话超时

使用 Spring 安全注册创建会话

春季/安全中的自定义会话超时