欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-30 23:50:41
应用场景 最近社区总有人发文章带上小广告,严重影响社区氛围,好气!对于这种类型的用户,就该永久拉黑! 社区的安全框架使用了 spring-security 和 spri...

应用场景

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。