Keep Track of Logged In Users with Spring Security – 用Spring Security跟踪登录用户的情况

最后修改: 2016年 6月 29日


1. Overview


In this quick tutorial, we’re going to show an example of how we can track the currently logged in users in an application using Spring Security.

在这个快速教程中,我们将展示一个例子,说明我们如何使用Spring Security追踪应用程序中当前登录的用户。

For this purpose, we’re going to keep track of a list of logged in users by adding the user when they log in and removing them when they log out.


We’ll leverage the HttpSessionBindingListener to update the list of logged in users whenever user information is added to the session or removed from the session based on user logs into the system or logs out from the system.


2. Active User Store


For simplicity, we will define a class that acts as an in-memory store for the logged in users:


public class ActiveUserStore {

    public List<String> users;

    public ActiveUserStore() {
        users = new ArrayList<String>();

    // standard getter and setter

We’ll define this as a standard bean in the Spring context:


public ActiveUserStore activeUserStore(){
    return new ActiveUserStore();

3. The HTTPSessionBindingListener


Now, we’re going to make use of the HTTPSessionBindingListener interface and create a wrapper class to represent a user that is currently logged in.


This will basically listen to events of type HttpSessionBindingEvent, which are triggered whenever a value is set or removed, or, in other words, bound or unbound, to the HTTP session:


public class LoggedUser implements HttpSessionBindingListener, Serializable {

    private static final long serialVersionUID = 1L;
    private String username; 
    private ActiveUserStore activeUserStore;
    public LoggedUser(String username, ActiveUserStore activeUserStore) {
        this.username = username;
        this.activeUserStore = activeUserStore;
    public LoggedUser() {}

    public void valueBound(HttpSessionBindingEvent event) {
        List<String> users = activeUserStore.getUsers();
        LoggedUser user = (LoggedUser) event.getValue();
        if (!users.contains(user.getUsername())) {

    public void valueUnbound(HttpSessionBindingEvent event) {
        List<String> users = activeUserStore.getUsers();
        LoggedUser user = (LoggedUser) event.getValue();
        if (users.contains(user.getUsername())) {

    // standard getter and setter

The listener has two methods that need to be implemented, valueBound() and valueUnbound() for the two types of actions that trigger the event it is listening for. Whenever a value of the type that implements the listener is set or removed from the session, or the session is invalidated, these two methods will be invoked.


In our case, the valueBound() method will be called when the user logs in and the valueUnbound() method will be called when the user logs out or when the session expires.


In each of the methods we retrieve the value associated with the event, then add or remove the username from our list of logged in users, depending on whether the value was bound or unbound from the session.


4. Tracking Login and Logout


Now we need to keep track of when the user is successfully logged in or logged out so that we can add or remove an active user from the session. In a Spring Security application, this can be achieved by implementing the AuthenticationSuccessHandler and LogoutSuccessHandler interfaces.

现在我们需要跟踪用户何时成功登录或注销,这样我们就可以从会话中添加或删除一个活动用户。在Spring Security应用程序中,这可以通过实现AuthenticationSuccessHandlerLogoutSuccessHandler接口来实现。

4.1. Implementing AuthenticationSuccessHandler


For the login action, we will set the username of the user logging in as an attribute on the session by overriding the onAuthenticationSuccess() method which provides us access to the session and authentication objects:


public class MySimpleUrlAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    ActiveUserStore activeUserStore;
    public void onAuthenticationSuccess(HttpServletRequest request, 
      HttpServletResponse response, Authentication authentication) 
      throws IOException {
        HttpSession session = request.getSession(false);
        if (session != null) {
            LoggedUser user = new LoggedUser(authentication.getName(), activeUserStore);
            session.setAttribute("user", user);

4.2. Implementing LogoutSuccessHandler


For the logout action, we will remove the user attribute by override the onLogoutSuccess() method of the LogoutSuccessHandler interface:


public class MyLogoutSuccessHandler implements LogoutSuccessHandler{
    public void onLogoutSuccess(HttpServletRequest request, 
      HttpServletResponse response, Authentication authentication)
      throws IOException, ServletException {
        HttpSession session = request.getSession();
        if (session != null){

5. Controller and View


In order to see all the above in action, we will create a controller mapping for the URL “/users” that will retrieve the list of users, add it as a model attribute and return the users.html view:

为了看到上述所有的行动,我们将为URL “/users”创建一个控制器映射,该映射将检索用户列表,将其作为一个模型属性添加,并返回users.html视图。

5.1. Controller


public class UserController {
    ActiveUserStore activeUserStore;

    public String getLoggedUsers(Locale locale, Model model) {
        model.addAttribute("users", activeUserStore.getUsers());
        return "users";

5.2. Users.html


    <h2>Currently logged in users</h2>
    <div th:each="user : ${users}">
        <p th:text="${user}">user</p>

6. Alternative Method Using Sessionregistry


Another method of retrieving the currently logged in users is by leveraging Spring’s SessionRegistry, which is a class that manages users and sessions. This class has the method getAllPrincipals() to obtain the list of users.


For each user, we can see a list of all their sessions by calling the method getAllSessions(). In order to obtain only the currently logged in users, we have to exclude the expired sessions, by setting the second parameter of getAllSessions() to false:


private SessionRegistry sessionRegistry;

public List<String> getUsersFromSessionRegistry() {
    return sessionRegistry.getAllPrincipals().stream()
      .filter(u -> !sessionRegistry.getAllSessions(u, false).isEmpty())

In order to use the SessionRegistry class, we have to define the bean and apply it to the session management as shown below:




public SessionRegistry sessionRegistry() {
    return new SessionRegistryImpl();

7. Conclusion


In this article, we have demonstrated how we can determine who the currently logged in users are in a Spring Security application.

在这篇文章中,我们已经演示了如何在Spring Security应用程序中确定谁是当前登录的用户。

The implementation of this tutorial can be found in the GitHub project – this is a Maven based project, so it should be easy to import and run as it is.