Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get all logged users in Spring Security

I would like to get list of all users which are currently logged in my application. I know, that I should inject SessionRegistry in my code to call getAllPrincipals() method. Unfortunatelly, I always get empty list. It seems that SessionRegistry is not populate and I don't know how to make it. I know, that on StackOverflow there are similar questions, but I still have problem with solving my problem. Firstly I add to my web.xml this code:

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

As I know it allows to get information about lifecycle (create, destroy) of sessions. And that's all. I have big problem with moving forward. My file with security beans is presented below:

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

Here I call getAllPrinciples() method:

@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";               
    }
}

I tried to add session-managemenent code into my http, ConcurrentSessionFilter and similar things, but in fact I don't understand it. And the documentation is too complex for me. Does anyone could help me and tell step by step what to do next? Which beans should I add?

like image 301
mchrobok Avatar asked Jan 12 '13 20:01

mchrobok


People also ask

How can I have list of all users logged in via Spring Security my web application?

How can I have list of all users logged in via Spring Security my web application? For accessing the list of all logged in users you need to inject SessionRegistry instance to your bean. But before injecting session registry you need to define session management part in your spring-security.

What is SecurityContextHolder getContext () getAuthentication ()?

The HttpServletRequest.getUserPrincipal() will return the result of SecurityContextHolder.getContext().getAuthentication() . This means it is an Authentication which is typically an instance of UsernamePasswordAuthenticationToken when using username and password based authentication.


1 Answers

I think you are almost there. The only thing you've probably missed is the use of session-registry-alias. By using that attribute on the concurrency-control element you expose the session registry, so that it can be injected to your own beans. See the reference doc.

So what you need is:

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

Now you have a reference to the session registry that will be populated by the ConcurrentSessionControlStrategy which is set up implicitly by the above configuration. To use it you would just inject it to your bean as normal:

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

Please note that the above configuration will also restrict the number of concurrent sessions a user may have. If you don't want this restriction, you will have to forgo the convenience of the namespace configuration, because the namespace schema doesn't allow you to set the max-sessions attribute to -1. If you need help on how to wire up the necessary beans manually, the reference doc gives detailed instructions on that.

like image 103
zagyi Avatar answered Oct 18 '22 00:10

zagyi