应用场景
最近社区总有人发文章带上小广告,严重影响社区氛围,好气!对于这种类型的用户,就该永久拉黑!
社区的安全框架使用了 spring-security 和 spring-session,登录状态 30 天有效,session 信息是存在 redis 中,如何优雅地处理这些不老实的用户呢?
首先,简单划分下用户的权限:
管理员(role_manager):基本操作 + 管理操作
普通用户(role_user):基本操作
拉黑用户(role_black):不允许登录
然后,拉黑指定用户(role_user -> role_black),再强制该用户退出即可(删除该用户在 redis 中 session 信息)。
项目相关依赖及配置
maven 依赖
org.springframework.boot
spring-boot-starter-security
org.springframework.boot
spring-boot-starter-data-redis
org.springframework.session
spring-session-data-redis
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 usersessions = sessionrepository.findbyindexnameandindexvalue(findbyindexnamesessionrepository.principal_name_index_name, indexname);
// 移除用户的 session 信息
list sessionids = new arraylist<>(usersessions.keyset());
for (string session : sessionids) {
redisoperationssessionrepository.deletebyid(session);
}
return responsebean.success(usersessions);
}
}
说明 indexname 为 principal.getname() 的返回值。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持萬仟网。
希望与广大网友互动??
点此进行留言吧!