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

时间:2013-01-12 20:20:00

标签: spring session spring-security

我想获取当前登录到我的应用程序的所有用户的列表。我知道,我应该在我的代码中注入SessionRegistry来调用getAllPrincipals()方法。不幸的是,我总是得到空名单。似乎SessionRegistry没有填充,我不知道如何制作它。我知道,在StackOverflow上有类似的问题,但我仍然有解决问题的问题。首先,我将这段代码添加到我的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 个答案:

答案 0 :(得分:6)

我想你差不多了。您可能唯一遗漏的是使用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