How can I get a list of all registered users (via spring security) my web application

I use Spring Security in my web application, and now I want to get a list of all the users who are logged into my program.

How can I access this list? Aren't they somewhere in the spring framework? Like SecurityContextHolder or SecurityContextRepository ?

+59
spring spring-security web-applications login user
Jun 30 2018-12-12T00:
source share
7 answers

To access the list of all registered users, you need to enter an instance of SessionRegistry on your bean.

@Autowired @Qualifier("sessionRegistry") private SessionRegistry sessionRegistry; 

And then, using the tested SessionRegistry, you can access the list of all participants:

 List<Object> principals = sessionRegistry.getAllPrincipals(); List<String> usersNamesList = new ArrayList<String>(); for (Object principal: principals) { if (principal instanceof User) { usersNamesList.add(((User) principal).getUsername()); } } 

But before you enter the session registry, you need to define the session management part in spring -security.xml (see the "Session Management" section in Spring's security reference documentation ) and in the concurrency -control section you must set an alias for the session registry object ( session-registry-alias) with which you will enter it.

  <security:http access-denied-page="/error403.jsp" use-expressions="true" auto-config="false"> <security:session-management session-fixation-protection="migrateSession" session-authentication-error-url="/login.jsp?authFailed=true"> <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" expired-url="/login.html" session-registry-alias="sessionRegistry"/> </security:session-management> ... </security:http> 
+58
Jun 30 2018-12-12T00:
source share

In JavaConfig, it will look like this:

 @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(final HttpSecurity http) throws Exception { // ... http.sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry()); } @Bean public SessionRegistry sessionRegistry() { return new SessionRegistryImpl(); } @Bean public ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() { return new ServletListenerRegistrationBean<HttpSessionEventPublisher>(new HttpSessionEventPublisher()); } } 

With the calling code looking like this:

 public class UserController { @Autowired private SessionRegistry sessionRegistry; public void listLoggedInUsers() { final List<Object> allPrincipals = sessionRegistry.getAllPrincipals(); for(final Object principal : allPrincipals) { if(principal instanceof SecurityUser) { final SecurityUser user = (SecurityUser) principal; // Do something with user System.out.println(user); } } } } 

Please note that SecurityUser is my own class that implements UserDetails .

+29
Nov 27 '14 at 4:55
source share

Please correct me if I am wrong.

I think @ Adam's answer is incomplete. I noticed that sessions that have already expired in the list appear again.

 public class UserController { @Autowired private SessionRegistry sessionRegistry; public void listLoggedInUsers() { final List<Object> allPrincipals = sessionRegistry.getAllPrincipals(); for (final Object principal : allPrincipals) { if (principal instanceof SecurityUser) { final SecurityUser user = (SecurityUser) principal; List<SessionInformation> activeUserSessions = sessionRegistry.getAllSessions(principal, /* includeExpiredSessions */ false); // Should not return null; if (!activeUserSessions.isEmpty()) { // Do something with user System.out.println(user); } } } } } 

Hope it helps.

+7
Jul 04 '16 at 23:04
source share

Please correct me if I am wrong.

I think the @Adam and @elysch answer is incomplete. I noticed that you need to add a listener:

  servletContext.addListener(HttpSessionEventPublisher.class); 

to

 public class AppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) { ... servletContext.addListener(HttpSessionEventPublisher.class); } 

with security conf:

 @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(final HttpSecurity http) throws Exception { // ... http.sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry()); } @Bean public SessionRegistry sessionRegistry() { return new SessionRegistryImpl(); } @Bean public HttpSessionEventPublisher httpSessionEventPublisher() { return new HttpSessionEventPublisher(); } } 

And then you get online users!

+6
Mar 09 '17 at 11:03 on
source share

You need to implement SessionRegistry (as mentioned earlier), and then you can do it in a single pipeline as follows:

 public List<UserDetails> findAllLoggedInUsers() { return sessionRegistry.getAllPrincipals() .stream() .filter(principal -> principal instanceof UserDetails) .map(UserDetails.class::cast) .collect(Collectors.toList()); } 
+1
Sep 24 '18 at 9:24
source share

Found this note very important and relevant:

"[21] Authentication using mechanisms that perform redirection after authentication (such as logging in) will not be detected by SessionManagementFilter, as the filter will not be called during the authentication request. Session management functionality should be handled separately in these cases."

https://docs.spring.io/spring-security/site/docs/3.1.x/reference/session-mgmt.html#d0e4399

Also, obviously, many people have trouble getting sessionRegistry.getAllPrincipals () that returns something other than an empty array. In my case, I fixed this by adding sessionAuthenticationStrategy to my custom AuthenticationFilter:

 @Bean public CustomUsernamePasswordAuthenticationFilter authenticationFilter() throws Exception { ... authenticationFilter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy()); } @Bean public SessionRegistry sessionRegistry() { return new SessionRegistryImpl(); } //cf. https://stackoverflow.com/questions/32463022/sessionregistry-is-empty-when-i-use-concurrentsessioncontrolauthenticationstrate public SessionAuthenticationStrategy sessionAuthenticationStrategy() { List<SessionAuthenticationStrategy> stratList = new ArrayList<>(); SessionFixationProtectionStrategy concStrat = new SessionFixationProtectionStrategy(); stratList.add(concStrat); RegisterSessionAuthenticationStrategy regStrat = new RegisterSessionAuthenticationStrategy(sessionRegistry()); stratList.add(regStrat); CompositeSessionAuthenticationStrategy compStrat = new CompositeSessionAuthenticationStrategy(stratList); return compStrat; } 
0
Oct 24 '18 at 4:55
source share

Like @rolyanos solution, it always works for me:

- for the controller

 @RequestMapping(value = "/admin") public String admin(Map<String, Object> model) { if(sessionRegistry.getAllPrincipals().size() != 0) { logger.info("ACTIVE USER: " + sessionRegistry.getAllPrincipals().size()); model.put("activeuser", sessionRegistry.getAllPrincipals().size()); } else logger.warn("EMPTY" ); logger.debug(log_msg_a + " access ADMIN page. Access granted." + ANSI_RESET); return "admin"; } 

- for the front

 <tr th:each="activeuser, iterStat: ${activeuser}"> <th><b>Active users: </b></th> <td align="center" th:text="${activeuser}"></td> </tr> 

- for spring konfing

 @Bean public SessionRegistry sessionRegistry() { return new SessionRegistryImpl(); } @Bean public ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() { return new ServletListenerRegistrationBean<HttpSessionEventPublisher>(new HttpSessionEventPublisher()); } @Override protected void configure(HttpSecurity http) throws Exception { http.logout() .logoutSuccessUrl("/home") .logoutUrl("/logout") .invalidateHttpSession(true) .deleteCookies("JSESSIONID"); http.authorizeRequests() .antMatchers("/", "/home") .permitAll() .antMatchers("/admin") .hasRole("ADMIN") .anyRequest() .authenticated() .and() .formLogin() .loginPage("/home") .defaultSuccessUrl("/main") .permitAll() .and() .logout() .permitAll(); http.sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry()); http.authorizeRequests().antMatchers("/webjars/**").permitAll(); http.exceptionHandling().accessDeniedPage("/403"); } 
0
Dec 12 '18 at 16:22
source share



All Articles