Spring Security 强制退出指定用户的方法

网友投稿 565 2023-02-13


Spring Security 强制退出指定用户的方法

应用场景

最近社区总有人发文章带上小广告,严重影响社区氛围,好气!对于这种类型的用户,就该永久拉黑!

社区的安全框架使用了 spring-security 和 spring-session,登录状态 30 天有效,session 信息是存在 redis 中,如何优雅地处理这些不老实的用户呢?

首先,简单划分下用户的权限:

管理员(ROLE_MANAGER):基本操作 + 管理操作

普通用户(ROLE_USER):基本操作

拉黑用户(ROLE_BLACK):不允许登录

然后,拉黑指定用户(ROLE_USER -> ROLE_BLACK),再强制该用户退出即可(删除该用户在 redis 中 session 信息)。

项目相关依赖及配置

Maven 依赖

org.springframework.boot

spring-boot-starter-security

org.springframework.boot

spring-boot-starter-data-redis

org.springframework.session

spring-session-data-redis

Spring Session 策略配置 application.yml

# 此处省略 redis 连接相关配置

spring:

session:

store-type: redis

Spring Security 配置代码示例

@EnableWebSecurity

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override

protected void configure(HttpSecurity http) throws Exception {

http

.authorizeRequests()

.antMatchers("/user/**").authenticated()

.antMatchers("/manager/**").hasAnyRole(RoleEnum.MANAGER.getMessage())

.anyRequest().permitAll()

.and().formLogin().loginPage("/login").permitAll()

.and().logout().permitAll()

.and().csrf().disable();

}

}

强制退出指定给用户接口

import com.spring4all.bean.ResponseBean;

import com.spring4all.service.UserService;

import lombok.AllArgsConstructor;

import org.springframework.session.FindByIndexNameSessionRepository;

import org.springframework.session.Session;

import org.springframework.session.data.redis.RedisOperationsSessionRepository;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;

@RestController

@AllArgsConstructor

public class UserManageApi {

private final FindByIndexNameSessionRepository extends Session> sessionRepository;

private final RedisOperationsSessionRepository redisOperationsSessionRepository;

private final UserService userService;

/**

* 管理指定用户退出登录

* @param userId 用户ID

* @return 用户 Session 信息

*/

@PreAuthorize("hasRole('MANAGER')")

@GetMappingPRykrHBF("/manager/logout/{userId}")

public ResponseBean data(@PathVariable() Long userId){

// 查询 PrincipalNameIndexName(Redis 用户信息的 key),结合自身业务逻辑来实现

String indexName = userService.getPrincipalNameIndexName(userId);

// 查询用户的 Session 信息,返回值 key 为 sessionId

Map userSessions = sessionRepository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, indexName);

// 移除用户的 session 信息

List sessionIds = new ArrayList<>(userSessions.keySet());

for (String session : sessionIds) {

redisOperationsSessionRepository.deleteById(session);

}

return ResponseBean.success(userSessions);

}

}

说明 indexName 为 Principal.getName() 的返回值。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:浏览器接口测试(浏览器接口测试教程)
下一篇:亚马逊接口开发(亚马逊接口开发 spapi)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~