Как я могу иметь список всех пользователей, вошедших в систему (через spring security) мое веб-приложение
Я использую spring security в своем веб-приложении, и теперь я хочу иметь список всех пользователей, которые вошли в мою программу.
Как я могу получить доступ к этому списку? Разве они уже не хранятся где-то в рамках spring? Как или SecurityContextRepository?
5 ответов:
для доступа к списку всех зарегистрированных пользователей вам необходимо ввести экземпляр SessionRegistry в ваш компонент.
@Autowired @Qualifier("sessionRegistry") private SessionRegistry sessionRegistry;а затем с помощью injcted SessionRegistry вы можете получить доступ к списку всех участников:
List<Object> principals = sessionRegistry.getAllPrincipals(); List<String> usersNamesList = new ArrayList<String>(); for (Object principal: principals) { if (principal instanceof User) { usersNamesList.add(((User) principal).getUsername()); } }но прежде чем вводить реестр сеансов, вам нужно определить часть управления сеансами в вашей spring-security.xml (посмотрите на раздел управления сеансами в справочной документации по безопасности Spring) и в разделе управления параллелизмом вы следует установить псевдоним для объекта реестра сеанса (session-registry-alias), С помощью которого вы будете вводить его.
<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>
в JavaConfig, это будет выглядеть так:
@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()); } }С вызывающим кодом, который выглядит так:
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); } } } }отметим, что
SecurityUser- Это мой собственный класс, который реализуетUserDetails.
пожалуйста, поправьте меня, если я ошибаюсь.
Я думаю @Адама!--5--> ответ неполный. Я заметил, что сеансы уже истек в списке появлялись снова.
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); } } } } }надеюсь, что это помогает.
пожалуйста, поправьте меня, если я тоже ошибаюсь.
Я думаю, что ответ @Adam и @elysch является неполным. Я заметил, что там нужно добавить слушателя:
servletContext.addListener(HttpSessionEventPublisher.class);до
public class AppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) { ... servletContext.addListener(HttpSessionEventPublisher.class); }С безопасностью 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(); } }и тогда вы получите текущих пользователей онлайн!
вам нужно впрыснуть
SessionRegistry(Как уже упоминалось eariler), а затем вы можете сделать это в одном конвейере, как это:public List<UserDetails> findAllLoggedInUsers() { return sessionRegistry.getAllPrincipals() .stream() .filter(principal -> principal instanceof UserDetails) .map(UserDetails.class::cast) .collect(Collectors.toList()); }
Comments