Mat*_* Kh 66 spring login web-applications spring-security
我在我的Web应用程序中使用spring security,现在我想要列出所有登录我程序的用户.
我怎样才能访问该列表?它们不是已经存在于spring框架内的某个地方吗?像SecurityContextHolder或SecurityContextRepository?
dim*_*mas 59
要访问所有登录用户的列表,您需要将SessionRegistry实例注入您的bean.
@Autowired
@Qualifier("sessionRegistry")
private SessionRegistry sessionRegistry;
Run Code Online (Sandbox Code Playgroud)
然后使用受惩罚的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());
}
}
Run Code Online (Sandbox Code Playgroud)
但是在注入会话注册表之前,您需要在spring-security.xml中定义会话管理部分(请参阅Spring Security参考文档中的会话管理部分),在并发控制部分中,您应该为会话注册表对象设置别名(会话注册表 -别名)你将通过它注入它.
<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>
Run Code Online (Sandbox Code Playgroud)
Ada*_*dam 38
在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());
}
}
Run Code Online (Sandbox Code Playgroud)
调用代码如下所示:
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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这SecurityUser是我自己的实现类UserDetails.
如果我错了,请纠正我.
我认为@Adam的答案是不完整的.我注意到列表中已经过期的会话再次出现.
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);
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你.
小智 6
如果我错了也请纠正我.
我认为@ Adam和@ elysch的回答是不完整的.我注意到需要添加监听器:
servletContext.addListener(HttpSessionEventPublisher.class);
Run Code Online (Sandbox Code Playgroud)
至
public class AppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
...
servletContext.addListener(HttpSessionEventPublisher.class);
}
Run Code Online (Sandbox Code Playgroud)
与安全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();
}
}
Run Code Online (Sandbox Code Playgroud)
然后你将获得当前的在线用户!
您需要注入SessionRegistry(如前所述),然后您可以在一个管道中执行此操作,如下所示:
public List<UserDetails> findAllLoggedInUsers() {
return sessionRegistry.getAllPrincipals()
.stream()
.filter(principal -> principal instanceof UserDetails)
.map(UserDetails.class::cast)
.collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
41332 次 |
| 最近记录: |