Spring Security 强制退出指定用户的方法
作者:Anoyi 发布时间:2022-10-04 18:13:04
标签:Spring,Security,强制退出
应用场景
最近社区总有人发文章带上小广告,严重影响社区氛围,好气!对于这种类型的用户,就该永久拉黑!
社区的安全框架使用了 spring-security 和 spring-session,登录状态 30 天有效,session 信息是存在 redis 中,如何优雅地处理这些不老实的用户呢?
首先,简单划分下用户的权限:
管理员(ROLE_MANAGER):基本操作 + 管理操作
普通用户(ROLE_USER):基本操作
拉黑用户(ROLE_BLACK):不允许登录
然后,拉黑指定用户(ROLE_USER -> ROLE_BLACK),再强制该用户退出即可(删除该用户在 redis 中 session 信息)。
项目相关依赖及配置
Maven 依赖
<!-- 安全 Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Spring Session Redis -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
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')")
@GetMapping("/manager/logout/{userId}")
public ResponseBean data(@PathVariable() Long userId){
// 查询 PrincipalNameIndexName(Redis 用户信息的 key),结合自身业务逻辑来实现
String indexName = userService.getPrincipalNameIndexName(userId);
// 查询用户的 Session 信息,返回值 key 为 sessionId
Map<String, ? extends Session> userSessions = sessionRepository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, indexName);
// 移除用户的 session 信息
List<String> sessionIds = new ArrayList<>(userSessions.keySet());
for (String session : sessionIds) {
redisOperationsSessionRepository.deleteById(session);
}
return ResponseBean.success(userSessions);
}
}
说明 indexName 为 Principal.getName() 的返回值。
来源:https://www.jianshu.com/p/7766e0b9d98f
0
投稿
猜你喜欢
- 实现“摇一摇”功能,其实很简单,就是检测手机的重力感应,具体实现代码如下:1、在 AndroidManifest.xml 中添加操作权限2、
- 我们平时使用的一些常见队列都是非阻塞队列,比如PriorityQueue、LinkedList(LinkedList是双向链表,它实现了De
- 1.设置url-pattern为*.do(最为常见的方式)只要你的请求url中包含配置的url-pattern,该url就可以到达Dispa
- Java有一种特殊线程,守护线程,这种线程优先级特别低,只有在同一程序中的其他线程不执行时才会执行。由于守护线程拥有这些特性,所以,一般用为
- Mapper 就是“映射”的意思,Mapper 文件时 Mybatis 中的 SQL 语句的配置文件
- 本文主要和大家分享介绍了关于Java JDK * 使用的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍:前言代理是一种常用的
- Spring介绍:spring 使用基本的 JavaBean 来完成以前只可能由 EJB 完成的事情。然而, Spring的用途不仅限于服务
- 持久层的那些事什么是 JDBCJDBC(JavaDataBase Connectivity)就是 Java 数据库连接, 说的直白点就是 使
- ObjectMapper 忽略字段大小写核心代码:ObjectMapper mapper = new ObjectMapper();mapp
- public static String toUtf8String(String s) {
- controller传boolean形式值@GetMapping("/check-cart")public List&l
- 前导:发过程中经常会使用java将office系列文档转换为PDF, 一般都使用微软提供的openoffice+jodconverter 实
- 本文实例讲述了Java中计算时间差的方法。分享给大家供大家参考。具体如下:假设现在是2004-03-26 13:31:40过去是:2004-
- 1、mybatis-plus相信大家在日常的开发中用的最多的就是 mybatis-plus了吧,作为一个 MyBatis (opens ne
- 本文实例讲述了java设计模式之工厂模式。分享给大家供大家参考,具体如下:工厂模式(factory)涉及到4个角色:抽象工厂类角色,具体工厂
- (注意:本文基于JDK1.8)前言增删改查,修改元素,Vector提供了3个方法,包括迭代器中的一个,不过本文只分析Vector自身的两个修
- 前言在java Thread类中,我们会看到interrupt()、interrupted()及isInterrupted(),在大多数情况
- synchronized原理在java中,每一个对象有且仅有一个同步锁。这也意味着,同步锁是依赖于对象而存在。当我们调用某对象的synchr
- 前言学习了关于集合类的知识,我们可以做一个小项目来加深对集合类知识的学习!一、项目要求代码实现,一副扑克牌(不包括大小王)的购买、打乱、发牌
- 错误处理到目前为止,我们都没怎么介绍onComplete()和onError()函数。这两个函数用来通知订阅者,被观察的对象将停止发送数据以