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

作者:Anoyi 时间:2022-10-04 18:13:04 

应用场景

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

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

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

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

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

  3. 拉黑用户(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

标签:Spring,Security,强制退出
0
投稿

猜你喜欢

  • 详解kotlin中::双冒号的使用

    2022-09-04 10:17:23
  • C#中把英文字母转换为大写或小写的方法

    2021-06-13 18:46:55
  • C#中的IEnumerable简介及简单实现实例

    2023-07-15 22:27:07
  • Java 面向对象和封装全面梳理总结

    2023-10-16 08:20:27
  • Java使用JDBC实现Oracle用户认证的方法详解

    2022-10-06 08:59:36
  • SWT(JFace) Menu、Bar...体验代码

    2022-01-29 08:34:46
  • Android实现简单音乐播放器(MediaPlayer)

    2023-04-24 19:28:57
  • 浅谈Android手机的抢红包插件

    2021-08-13 01:04:36
  • 超详细的Intellij IDEA 看源码必备技能

    2021-10-27 09:03:16
  • 深入理解Java设计模式之抽象工厂模式

    2023-11-28 12:11:34
  • Java实现三子棋小游戏

    2022-09-12 01:27:20
  • spring boot validation参数校验实例分析

    2023-02-03 02:50:38
  • 分享java中设置代理的两种方式

    2023-10-28 10:48:52
  • Android跳转三方应用实例代码

    2022-02-01 11:15:42
  • Android如何通过scheme跳转界面

    2021-08-11 05:19:41
  • 详解SpringBoot通用配置文件(不定时更新)

    2022-12-01 09:07:04
  • Android自定义可标记日历效果

    2022-09-06 04:11:22
  • C#学习基础概念二十五问 11-15

    2022-04-18 04:19:00
  • Echarts+SpringMvc显示后台实时数据

    2021-06-08 03:38:42
  • C#图片压缩的实现方法

    2022-07-01 21:26:12
  • asp之家 软件编程 m.aspxhome.com