一、SPEL表达式权限控制

  从spring security 3.0开始已经可以使用spring Expression表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。Spring Security可用表达式对象的基类是SecurityExpressionRoot。

使用Spring安全表达式控制系统功能访问权限_第1张图片

  部分朋友可能会对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。

使用Spring安全表达式控制系统功能访问权限_第2张图片

  对于/person/{id}对应的资源的访问,调用rbacService的bean的方法checkUserId进行权限验证,传递参数为authentication对象和person的id。该id为PathVariable,以#开头表示。

使用Spring安全表达式控制系统功能访问权限_第3张图片

  三、 Method表达式安全控制

  如果我们想实现方法级别的安全配置,Spring Security提供了四种注解,分别是@PreAuthorize , @PreFilter , @PostAuthorize 和 @PostFilter

  3.1.开启方法级别注解的配置

  在Spring安全配置代码中,加上EnableGlobalMethodSecurity注解,开启方法级别安全配置功能。

使用Spring安全表达式控制系统功能访问权限_第4张图片

  3.2 使用PreAuthorize注解

  @PreAuthorize 注解适合进入方法前的权限验证。只有拥有ADMIN角色才能访问findAll方法。

  @PreAuthorize(hasRole('ADMIN'))

  ListfindAll();

  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(Listids, Listusernames) {

  3.5 使用PostFilter 注解

  PostFilter 针对返回结果进行过滤,特别适用于集合类返回值,过滤集合中不符合表达式的对象。

使用Spring安全表达式控制系统功能访问权限_第5张图片