前言
2021SC@SDUSC
概述
在本次的博客里,我们续接上一次的内容,对项目的身份校验与权限控制进行进一步的分析。上一次我们以身份校验为主要内容,讲解了jwt+spring security+filter技术来实现身份校验的配置以及流程和代码的实现机制等。接下来我们就权限控制的内容进行分析,来看一看对于权限是如何管理的。
权限控制
Spring Security 的权限控制方式:
表达式控制 URL 路径权限
表达式控制方法权限
使用过滤注解
动态权限
1.表达式控制 URL 路径权限
Spring Security 支持在 URL 和方法权限控制时使用 SpEL 表达式,如果表达式返回值为 true 则表示需要对应的权限,否则表示不需要对应的权限。提供表达式的类是 SecurityExpressionRoot:
SecurityExpressionRoot 有两个实现类,表示在应对 URL 权限控制和应对方法权限控制时,分别对 SpEL 所做的拓展,例如在基于 URL 路径做权限控制时,增加了 hasIpAddress 选项。
SecurityExpressionRoot 类中定义的最基本的 SpEL 有:
2.表达式控制方法权限
在方法上添加注解来控制权限,使用方法非常灵活。
例如:
@PreAuthorize:方法执行前进行权限检查,@PreAuthorize 声明这个方法所需要的权限表达式,例如:@PreAuthorize("hasAuthority('sys:dept:delete')"),
根据这个注解所需要的权限,再和当前登录的用户角色所拥有的权限对比,如果用户的角色权限集Set中有这个权限,则放行;没有,拒绝
具体代码流程可参考:@PreAuthorize 权限控制的原理 - 简书
@PostAuthorize:方法执行后进行权限检查,较少用到
@Secured:类似于 @PreAuthorize
2.使用过滤注解
Spring Security 中有两个过滤函数 @PreFilter 和 @PostFilter,可以对集合类型的参数或返回值进行过滤。使用@PreFilter和@PostFilter时,Spring Security将移除使对应表达式的结果为false的元素。
@PostFilter("filterObject.id%2==0")
public List<User> findAll() {
List<User> userList = new ArrayList<User>();
User user;
for (int i=0; i<10; i++) {
user = new User();
user.setId(i);
userList.add(user);
}
return userList;
}
上述代码表示将对返回结果中id不为偶数的user进行移除。filterObject是使用@PreFilter和@PostFilter时的一个内置表达式,表示集合中的当前对象。当@PreFilter标注的方法拥有多个集合类型的参数时,需要通过@PreFilter的filterTarget属性指定当前@PreFilter是针对哪个参数进行过滤的。
如下面代码就通过filterTarget指定了当前@PreFilter是用来过滤参数ids的。
@PreFilter(filterTarget="ids", value="filterObject%2==0")
public void delete(List<Integer> ids, List<String> usernames) {
...
}
4.动态权限
自定义权限内容,一般通过filter来实现
原理分析
架构分析:
代码流程可参考:
深入理解Spring Security授权机制原理 - 朱季谦 - 博客园