欢迎来到代码驿站!

JAVA代码

当前位置:首页 > 软件编程 > JAVA代码

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

时间:2021-05-19 09:42:27|栏目:JAVA代码|点击:

应用场景

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

社区的安全框架使用了 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() 的返回值。

上一篇:SpringMVC表单标签使用详解

栏    目:JAVA代码

下一篇:SpringCloud Zuul过滤器和谷歌Gauva实现限流

本文标题:Spring Security 强制退出指定用户的方法

本文地址:http://www.codeinn.net/misctech/124788.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有