使用Spring安全表达式控制系统功能访问权限问题
一、SPEL表达式权限控制
从springsecurity3.0开始已经可以使用springExpression表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。SpringSecurity可用表达式对象的基类是SecurityExpressionRoot。
表达式函数 | 描述 |
---|---|
hasRole([role]) | 用户拥有指定的角色时返回true(Springsecurity默认会带有ROLE_前缀),去除前缀参考RemovetheROLE_ |
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')orhasAuthority('USER')") .anyRequest().authenticated();
这里我们定义了应用/person/*URL的范围,只有拥有ADMIN或者USER权限的用户才能访问这些person资源。
2.2.安全表达式中引用bean
这种方式,比较适合有复杂权限验证逻辑的情况,当SpringSecurity提供的默认表达式方法无法满足我们的需求的时候。首先我们定义一个权限验证的RbacService。
@Component("rbacService") @Slf4j publicclassRbacService{ //返回true表示验证通过 publicbooleanhasPermission(HttpServletRequestrequest,Authenticationauthentication){ //验证逻辑代码 returntrue; } publicbooleancheckUserId(Authenticationauthentication,intid){ //验证逻辑代码 returntrue; } }
对于"/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表达式安全控制
如果我们想实现方法级别的安全配置,SpringSecurity提供了四种注解,分别是@PreAuthorize,@PreFilter,@PostAuthorize和@PostFilter
3.1.开启方法级别注解的配置
在Spring安全配置代码中,加上EnableGlobalMethodSecurity注解,开启方法级别安全配置功能。
@Configuration @EnableGlobalMethodSecurity(prePostEnabled=true) publicclassMySecurityConfigextendsWebSecurityConfigurerAdapter{
3.2使用PreAuthorize注解
@PreAuthorize注解适合进入方法前的权限验证。只有拥有ADMIN角色才能访问findAll方法。
@PreAuthorize("hasRole('ADMIN')") ListfindAll();
3.3使用PostAuthorize注解
@PostAuthorize在方法执行后再进行权限验证,适合根据返回值结果进行权限验证。SpringEL提供返回对象能够在表达式语言中获取返回的对象returnObject。下文代码只有返回值的name等于authentication对象的name才能正确返回,否则抛出异常。
@PostAuthorize("returnObject.name==authentication.name") PersonfindOne(Integerid);
3.4使用PreFilter注解
PreFilter针对参数进行过滤,下文代码表示针对ids参数进行过滤,只有id为偶数才能访问delete方法。
//当有多个对象是使用filterTarget进行标注 @PreFilter(filterTarget="ids",value="filterObject%2==0") publicvoiddelete(Listids,List usernames){
3.5使用PostFilter注解
PostFilter针对返回结果进行过滤,特别适用于集合类返回值,过滤集合中不符合表达式的对象。
@PostFilter("filterObject.name==authentication.name") ListfindAll();
总结
以上所述是小编给大家介绍的使用Spring安全表达式控制系统功能访问权限问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。