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

使用Spring安全表达式控制系统功能访问权限

程序员文章站 2023-11-14 09:20:16
一、SPEL表达式权限控制 从 开始已经可以使用 表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。Spring Security可用表达式对象的基类是SecurityExpressionRoot。 | 表达式函数 | 描述 | | | | | ) | 用户拥有指定的角色时返回tr ......

一、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();

期待您的关注