spring - 如何排除不活跃用户?(春季安全)
问题描述
我得到了所有活动用户,但是当用户注销时,它仍然被列为活动用户。如何防止用户在注销后被列为活动用户?
我无法在文档中找到解决方案。
https://github.com/romanych2021/TestSession
谢谢。
ActiveUserServiceImpl.java
@Service
public class ActiveUserServiceImpl implements ActiveUserService{
@Autowired
SessionRegistry sessionRegistry;
public List<String > getAllActiveUser(){
List<Object> principals = sessionRegistry.getAllPrincipals();
User[] users = (User[]) principals.toArray(new User[0]);
return Arrays.stream(users)
.filter(user -> !sessionRegistry.getAllSessions(user, false)
.isEmpty()).map(User::getUsername).collect(Collectors.toList());
}
}
安全配置.java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.mvcMatchers("/").permitAll()
.mvcMatchers("/login").anonymous()
.mvcMatchers("/user", "/allUser").hasAnyRole("ADMIN", "USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login")
.defaultSuccessUrl("/")
.and().csrf().disable()
.logout()
.permitAll()
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.and().sessionManagement()
.maximumSessions(1)
.expiredUrl("/login")
.sessionRegistry(sessionRegistry);
}
}
HTML
<form method="post" action="/logout">
<button type="submit">Exit</button>
</form>
解决方案
将您的活动用户地图保留在 hashMap 中,并在当天注销时从该地图中删除被删除的用户。在 value unbound 事件中,您可以排除非活动用户。
@Getter
@Setter
public class ActiveUserStore {
public HashMap<String, ActorUser> userDetails;
public ActiveUserStore() {
userDetails = new HashMap<>();
}
}
@Getter
@Setter
public class LoggedUser implements HttpSessionBindingListener {
private ActorUser sessionUser;
private ActiveUserStore activeUserStore;
public LoggedUser(ActorUser sessionUser, ActiveUserStore activeUserStore) {
this.activeUserStore = activeUserStore;
this.sessionUser = sessionUser;
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
HashMap<String, ActorUser> userDetails = activeUserStore.getUserDetails();
LoggedUser loggedUser = (LoggedUser) event.getValue();
if (isNotNull(userDetails) && !userDetails.containsKey(loggedUser.getSessionUser().getUsername())) {
userDetails.put(loggedUser.getSessionUser().getUsername(), loggedUser.getSessionUser());
}
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
LoggedUser loggedUser = (LoggedUser) event.getValue();
HashMap<String, ActorUser> userDetails = activeUserStore.getUserDetails();
if (isNotNull(userDetails) && isNotNull(loggedUser.getSessionUser()) &&
userDetails.containsKey(loggedUser.getSessionUser().getUsername())) {
userDetails.remove(loggedUser.getSessionUser().getUsername());
}
}
推荐阅读
- git - 如何从 git log 中仅获取文件列表及其更改计数?
- selenium-webdriver - GGR 和 Selenoid 设置问题 - 无法在需要 selenoid 服务器机器上运行测试
- python - 如何使用 Tweepy 在 python 中过滤推文?
- vue.js - 如何在 Vue 中多次使用收音机作为组件?
- node.js - 在文件名中包含用户名
- firebase - Listview 在颤动中被提取后消失
- web-scraping - 在 html 网页中加载更多分页 - Webscraping
- mysql - mysql 输出文件/导出到 txt 文件,但保留 db 结构中的列长度
- python - 检查来自同一列表的不断增长的嵌套列表中是否存在项目
- c - CMake 找不到 minizip 但我可以使用 zlib