服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|JavaScript|易语言|

服务器之家 - 编程语言 - JAVA教程 - Spring Security 强制退出指定用户的方法

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

2021-04-10 13:33Anoyi JAVA教程

本篇文章主要介绍了Spring Security 强制退出指定用户的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

应用场景

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

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

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

  1. 管理员(ROLE_MANAGER):基本操作 + 管理操作
  2. 普通用户(ROLE_USER):基本操作
  3. 拉黑用户(ROLE_BLACK):不允许登录

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

项目相关依赖及配置

Maven 依赖

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- 安全 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

?
1
2
3
4
# 此处省略 redis 连接相关配置
spring:
 session:
  store-type: redis

Spring Security 配置代码示例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@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();
  }
 
}

强制退出指定给用户接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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

延伸 · 阅读

精彩推荐
  • JAVA教程MyBatis中#号与美元符号的区别

    MyBatis中#号与美元符号的区别

    #{变量名}可以进行预编译、类型匹配等操作,#{变量名}会转化为jdbc的类型。很多朋友不清楚在mybatis中#号与美元符号的不同,接下来通过本文给大家介绍两...

    java19936663062020-07-26
  • JAVA教程PriorityQueue 是线性结构吗?90% 的人都搞错了!

    PriorityQueue 是线性结构吗?90% 的人都搞错了!

    其实这个问题的完整描述是:Java 中的 PriorityQueue 实现,其数据的逻辑结构是线性结构吗?其数据的物理结构又是什么?...

    陈树义5832021-03-15
  • JAVA教程Java命令行下Jar包打包小结

    Java命令行下Jar包打包小结

    这篇文章主要介绍了Java命令行下Jar包打包小结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    Allocator11312021-03-08
  • JAVA教程Gradle使用Maven仓库的方法

    Gradle使用Maven仓库的方法

    本篇文章主要介绍了Gradle使用Maven仓库的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    Pansanday3482021-04-06
  • JAVA教程C#使用MySQLConnectorNet和MySQLDriverCS操作MySQL的方法

    C#使用MySQLConnectorNet和MySQLDriverCS操作MySQL的方法

    这篇文章主要介绍了C#使用MySQLConnectorNet和MySQLDriverCS操作MySQL的方法,相比普通方法能够在Windows下简化很多操作步骤,需要的朋友可以参考下 ...

    hzy37744172020-04-16
  • JAVA教程Spring Boot如何动态创建Bean示例代码

    Spring Boot如何动态创建Bean示例代码

    这篇文章主要给大家介绍了关于Spring Boot如何动态创建Bean的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值...

    西夏一品堂6832020-12-30
  • JAVA教程Java虚拟机工作原理

    Java虚拟机工作原理

    本文主要介绍了Java虚拟机的工作原理。具有很好的参考价值。下面跟着小编一起来看下吧...

    best.lei2232020-09-01
  • JAVA教程Java网络编程基础篇之单向通信

    Java网络编程基础篇之单向通信

    这篇文章主要介绍了Java网络编程里通过套接字实现单向通信的方法及相关实例,属于网络编程入门程序,虽然简单,但具有一定参考价值,需要的朋友可以...

    司机12272020-12-29