使用Spring安全表达式控制系统功能访问权限
一、SPEL表达式权限控制
从spring security 3.0
开始已经可以使用spring Expression
表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。Spring Security可用表达式对象的基类是SecurityExpressionRoot。
表达式函数 | 描述 |
---|---|
hasRole([role] ) |
用户拥有指定的角色时返回true (Spring security 默认会带有ROLE_ 前缀),去除前缀参考Remove the ROLE_ |
hasAnyRole([role1,role2]) |
用户拥有任意一个指定的角色时返回true |
hasAuthority([authority]) |
拥有某资源的访问权限时返回true |
hasAnyAuthority([auth1,auth2]) |
拥有某些资源其中部分资源的访问权限时返回true |
permitAll |
永远返回true |
denyAll |
永远返回false |
anonymous |
当前用户是anonymous 时返回true |
rememberMe |
当前用户是rememberMe 用户返回true |
authentication |
当前登录用户的authentication 对象 |
fullAuthenticated |
当前用户既不是anonymous 也不是rememberMe 用户时返回true |
hasIpAddress('192.168.1.0/24')) |
请求发送的IP匹配时返回true |
部分朋友可能会对Authority和Role有些混淆。Authority作为资源访问权限可大可小,可以是某按钮的访问权限(如资源ID:biz1),也可以是某类用户角色的访问权限(如资源ID:ADMIN)。当Authority作为角色资源权限时,hasAuthority('ROLE_ADMIN')与hasRole('ADMIN')是一样的效果。
二、SPEL在全局配置中的使用
我们可以通过继承WebSecurityConfigurerAdapter,实现相关的配置方法,进行全局的安全配置(之前的章节已经讲过) 。下面就为大家介绍一些如何在全局配置中使用SPEL表达式。
2.1.URL安全表达式
config.antMatchers("/system/*").access("hasAuthority('ADMIN') or hasAuthority('USER')")
.anyRequest().authenticated();
这里我们定义了应用/person/*
URL的范围,只有拥有ADMIN
或者USER
权限的用户才能访问这些person资源。
2.2.安全表达式中引用bean
这种方式,比较适合有复杂权限验证逻辑的情况,当Spring Security提供的默认表达式方法无法满足我们的需求的时候。首先我们定义一个权限验证的RbacService。
@Component("rbacService")
@Slf4j
public class RbacService {
//返回true表示验证通过
public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
//验证逻辑代码
return true;
}
public boolean checkUserId(Authentication authentication, int id) {
//验证逻辑代码
return true;
}
}
对于"/person/{id}"对应的资源的访问,调用rbacService的bean的方法checkUserId进行权限验证,传递参数为authentication对象和person的id。该id为PathVariable,以#开头表示。
config.antMatchers("/person/{id}").access("@rbacService.checkUserId(authentication,#id)")
.anyRequest().access("@rbacService.hasPermission(request,authentication)");
三、 Method表达式安全控制
如果我们想实现方法级别的安全配置,Spring Security
提供了四种注解,分别是@PreAuthorize
, @PreFilter
, @PostAuthorize
和 @PostFilter
3.1.开启方法级别注解的配置
在Spring安全配置代码中,加上EnableGlobalMethodSecurity注解,开启方法级别安全配置功能。
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
3.2 使用PreAuthorize注解
@PreAuthorize 注解适合进入方法前的权限验证。只有拥有ADMIN角色才能访问findAll方法。
@PreAuthorize("hasRole('ADMIN')")
List<Person> findAll();
3.3 使用PostAuthorize注解
@PostAuthorize 在方法执行后再进行权限验证,适合根据返回值结果进行权限验证。Spring EL
提供返回对象能够在表达式语言中获取返回的对象returnObject
。下文代码只有返回值的name等于authentication对象的name才能正确返回,否则抛出异常。
@PostAuthorize("returnObject.name == authentication.name")
Person findOne(Integer id);
3.4 使用PreFilter注解
PreFilter 针对参数进行过滤,下文代码表示针对ids参数进行过滤,只有id为偶数才能访问delete方法。
//当有多个对象是使用filterTarget进行标注
@PreFilter(filterTarget="ids", value="filterObject%2==0")
public void delete(List<Integer> ids, List<String> usernames) {
3.5 使用PostFilter 注解
PostFilter 针对返回结果进行过滤,特别适用于集合类返回值,过滤集合中不符合表达式的对象。
@PostFilter("filterObject.name == authentication.name")
List<Person> findAll();
期待您的关注
- 博主最近新写了一本书:《手摸手教您学习SpringBoot系列-16章97节》
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
最新文章
- 关于ScrollView嵌套ListView问题
- 架构实例之Demo_JSP_JavaBean
- vector的插入、lower_bound、upper_bound、equal_range实例
- SPY++的使用
- 个人学习笔记--MyBatis官方推荐DAO开发方案
- rhel安装eclipse
- 002-C语言概览
- Spark RDD设计学习笔记
- Java学习笔记16---抽象类与接口的浅显理解
- 关于vue的增删改查操作
- httpclient使用用例
- SQL2005数据库置疑处理
- stylie工具轻松搞定css3抛物线动画
- 第八章 计时器(BEEPER2)
- SQL Server Management Studio 教程一:设置sa用户登录
- 【POJ】1935 Journey(树形dp)
- 哪些工具可以在word中快速绘制图形
- css3之transform-origin
- SharpMap入门教程
- springboot+mybatis+thymeleaf+docker构建的个人站点开源项目(集成了个人主页、个人作品、个人博客)
热门文章
- CSRF漏洞实战靶场笔记
- SpringBoot系列:Spring Boot集成Spring Cache
- java集合之HashSet哈希SET基础
- 【MySQL】事务隔离级别及ACID
- python中函数定义与调用顺序问题
- pycharm在进行debug时不小心把console关闭了,恢复console的办法
- 解决Zend OPcache huge_code_pages: mmap(HUGETLB) failed: Cannot allocate memory报错
- TextBox各种设置
- 音视频入门-12-手动生成一张PNG图片
- vue-route动态路由