获取 Spring Security 中的所有登录用户

Posted

技术标签:

【中文标题】获取 Spring Security 中的所有登录用户【英文标题】:Get all logged users in Spring Security 【发布时间】:2012-12-27 04:20:51 【问题描述】:

我想获取当前登录我的应用程序的所有用户的列表。我知道,我应该在我的代码中注入SessionRegistry 来调用getAllPrincipals() 方法。不幸的是,我总是得到空列表。似乎 SessionRegistry 没有填充,我不知道如何制作它。我知道,在 *** 上有类似的问题,但我仍然无法解决我的问题。首先,我将这段代码添加到我的 web.xml 中:

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

据我所知,它允许获取有关会话生命周期(创建、销毁)的信息。就这样。我在前进方面遇到了很大的问题。我的带有安全 bean 的文件如下所示:

<beans:bean id="successAuth" class="pl.fp.microblog.auth.SuccessAuth"/>
<beans:bean id="failureAuth" class="pl.fp.microblog.auth.FailureAuth"/>

<http auto-config="true">
    <intercept-url pattern="/" access="ROLE_USER" />
    <intercept-url pattern="/profile/*" access="ROLE_USER" />
    <form-login 
        login-page="/login"         
        authentication-success-handler-ref="successAuth"
        authentication-failure-handler-ref="failureAuth"
        username-parameter="username"
        password-parameter="password"           
        login-processing-url="/login_processing_url"
    />          
    <security:logout logout-url="/logout_processing_url"/>  
    <session-management>
        <concurrency-control max-sessions="1" session-registry-alias="sessionRegistry"/>
    </session-management>
</http>

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

<beans:bean id="userService" class="pl.fp.microblog.auth.UserService">
    <beans:property name="userDAO" ref="userDAO"/>
</beans:bean>

<authentication-manager>
    <security:authentication-provider user-service-ref="userService">
        <password-encoder hash="sha-256">
            <security:salt-source ref="saltProvider"/>
        </password-encoder>         
    </security:authentication-provider>
</authentication-manager>

这里我调用getAllPrinciples()方法:

@Transactional
@Controller
public class SiteController 
    @Autowired
    private UserDAO userDAO;
    @Autowired
    private SessionRegistry sessionRegistry;    

    @RequestMapping(value = "profile/login")  
    public String profilePage(@PathVariable String login, HttpServletRequest req) throws SQLException      
        ...
        sessionRegistry.getAllPrincipals().size()
        ...     
        return "profile";               
    

我尝试将session-managemenent 代码添加到我的httpConcurrentSessionFilter 和类似的东西中,但实际上我不明白。而且文档对我来说太复杂了。有谁可以帮助我并逐步告诉我下一步该做什么?我应该添加哪些豆子?

【问题讨论】:

【参考方案1】:

我想你快到了。您可能错过的唯一一件事是使用session-registry-alias。通过在concurrency-control 元素上使用该属性,您可以公开会话注册表,以便可以将其注入您自己的bean。请参阅reference doc。

所以你需要的是:

<http auto-config="true">
...
    <session-management>
        <concurrency-control max-sessions="1" session-registry-alias="sessionRegistry"/>
    </session-management>
</http>

现在您有了对会话注册表的引用,该会话注册表将由上述配置隐式设置的ConcurrentSessionControlStrategy 填充。要使用它,你只需像往常一样将它注入到你的 bean 中:

<bean class="YourOwnSessionRegistryAwareBean">
    <property sessionRegistry="sessionRegistry"/>
</bean>

请注意,上述配置还将限制用户可能拥有的并发会话数。如果你不想要这个限制,你将不得不放弃命名空间配置的便利,因为命名空间模式不允许你将max-sessions 属性设置为-1。如果您需要有关如何手动连接必要 bean 的帮助,参考文档会提供 detailed instructions on that。

【讨论】:

是用用户成功登录后吗?奇怪,因为我在发布答案之前测试了配置,并且它有效,我可以在注册表中看到用户的会话。 顺便说一句,如果你自动装配它,你甚至不需要注册 bean 的别名,我想。如果它仍然不起作用,请确保您确实有一个经过身份验证的 http 会话。您也可以尝试在ConcurrentSessionControlStrategy.onAuthentication() 上设置断点的调试会话,检查用于注册新会话的会话注册表实例是否与您在调用getAllPrincipals() 时使用的相同。 嗯...在ConcurrentSessionControlStrategy.onAuthentication() 方法之后,sessionRegistry 中有 1 个条目(请参阅:i.imgur.com/S1bmg.png)。但在我的控制器中,它仍然是空列表。我认为注入了错误的sessionRegistry。但是如何解决呢? 此外,我将@Autowired private SessionRegistry sessionRegistry; 注入实现AuthenticationSuccessHandler 的类(在成功登录后运行)并且它可以工作。我不知道为什么我不能在我的控制器中进行相同的注入。 我注意到http 中的session-management 元素甚至都不需要。但我仍然只在authentication-success-handler-ref 类中获得正确数量的登录用户。在我的控制器中,我始终可以访问 SessionRegistry 的其他实例。

以上是关于获取 Spring Security 中的所有登录用户的主要内容,如果未能解决你的问题,请参考以下文章

您如何在 spring-security 中注销所有已登录的用户?

无法在 Spring Security 登录事件侦听器中获取“记住我”用户的会话 ID

页面获取Spring Security登录用户

Spring Security中的自动登录

如何在 Spring 获取之前捕获 Spring Security 登录表单?

spring security 获取当前登录用户