Spring Boot 2.x实战80 - Spring Security 4 - Spring Security的授权(Authorization)之方法安全

1.4.2 方法安全

Spring Security在方法级别进行权限控制,这样可以让权限控制更灵活。使用注解@EnableGlobalMethodSecurity开启方法安全注解的支持(组合了@Configuration注解):

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  //...
}

使用了prePostEnabled = true后可支持下面注解来进行方法安全控制,其它类型的注解本书不做讨论。

  • @PreAuthorize:通过访问控制表达式控制在方法调用前决定方法是否允许被调用;
  • @PreFilter:定义规则过滤注解方法的参数(集合),filterObject代表集合或数据里的当前对象;
  • @PostAuthorize:当方法被调用后,访问控制表达式将被检查,若检查返回值表达式可使用returnObject
  • @PostFilter:定义规则过滤方法返回值(集合或数组),filterObject代表集合或数据里的当前对象。

同样我们也要学习下方法安全的原理,web路径安全是从FilterSecurityInterceptor开始的 ,而方法安装时通过MethodSecurityInterceptor开始的,他们都是AbstractSecurityInterceptor的子类。

  • MethodSecurityInterceptor:对方法安全进行授权操作;它由@EnableGlobalMethodSecurity导入的配置GlobalMethodSecurityConfiguration初始化。MethodSecurityInterceptor还实现了AOP的MethodInterceptor接口来拦截注解方法;拦截方法调用AccessDecisionManager对注解方法进行授权操作。
    • MethodSecurityInterceptor:提取使用注解(如@PreAuthorize)的方法元数据并存储和提供查询功能,它是由PrePostAnnotationSecurityMetadataSource实现类提供功能的。
  • AccessDecisionManagerdecide方法中被保护的资源对象类型为MethodInvocation
  • AffirmativeBased:由一组AccessDecisionVoter进行投票来授权;
  • AccessDecisionVoter:方法安全控制的主要实现有:PreInvocationAuthorizationAdviceVoter,它使用ExpressionBasedPreInvocationAdvice对表达式进行计算,从而达到对方法的访问控制。

我们的演示控制器内容如下:

@RestController
public class IndexController {
    @GetMapping("/methodAdmin")
    @PreAuthorize("hasRole('ADMIN')") //1
    public String methodAdmin(){
        return "只有角色为ROLE_ADMIN的用户可访问";
    }

    @GetMapping("/methodDiffName")
    @PreAuthorize("#user.username != authentication.name") //2
    public String methodDiffName(@RequestBody  SysUser user){
        return "传输的用户名和当前用户名不相同的可访问";
    }

    @GetMapping("/methodNameThree")
    @PreAuthorize("@webSecurity.checkUsernameLenEq3(authentication)") //3
    public String methodNameThree(){
        return "只有用户名字符串长度为3的用户可以访问";
    }

    @GetMapping("/methodAnotherName3")
    @PostAuthorize("returnObject.length() == 5") //4
    public String anotherTree(@AuthenticationPrincipal SysUser sysUser){
        return "Hi" + sysUser.getUsername();
    }

    @GetMapping("/methodFilterIn")
    @PreAuthorize("hasRole('USER')")
    @PreFilter("filterObject%2 == 0") //5
    public List<Integer>  methodFilterIn (@RequestParam List<Integer> numbers){
        return numbers;
    }

    @GetMapping("/methodFilterOut")
    @PostFilter("hasRole('USER') and filterObject%2 == 0") //6
    public Integer[] methodFilterIn (){
        Integer[] numbers = {1,2,3,4,5,6,7,8,9};
        return numbers;
    }

}
  1. @PreAuthorize中表达式使用和Web路径安全一致;访问http://localhost:8080/methodAdmin,只有ROLE_ADMIN角色才能访问。
    在这里插入图片描述
  2. 可以使用#在表达式中获取参数中的数据;访问http://localhost:8080/methodDiffName,请求体中传递用户名,只有传递用户名和当前用户的用户名不一致才可访问。
    在这里插入图片描述
  3. 我们同样也可以在表达式中使用@调用Bean的方法;访问http://localhost:8080/methodNameThree,只有用户名字符串长度为3的用户可以访问。
    在这里插入图片描述
  4. 通过@PostAuthorize可对返回值进行检验;访问http://localhost:8080/methodAnotherName3,只有方法返回值字符串长度为5的用户才可访问。
    在这里插入图片描述
  5. 使用@PreFilter过滤参数的数据,参数只支持集合类不支持数组;访问:http://localhost:8080/methodFilterIn?numbers=1,2,3,4,5,6,7,8,9,10 ,将参数列表中只保留偶数。
    在这里插入图片描述
  6. 使用@PostFilter过滤返回值中的数据;访问http://localhost:8080/methodFilterOut,返回值列表中只包含偶数。
    在这里插入图片描述

新书推荐:

我的新书《从企业级开发到云原生微服务:Spring Boot 实战》已出版,内容涵盖了丰富Spring Boot开发的相关知识
购买地址:https://item.jd.com/12760084.html
在这里插入图片描述
主要包含目录有:

第一章 初识Spring Boot(快速领略Spring Boot的美丽)
第二章 开发必备工具(对常用开发工具进行介绍:包含IntelliJ IDEA、Gradle、Lombok、Docker等)
第三章 函数式编程
第四章 Spring 5.x基础(以Spring 5.2.x为基础)
第五章 深入Spring Boot(以Spring Boot 2.2.x为基础)
第六章 Spring Web MVC
第七章 数据访问(包含Spring Data JPA、Spring Data Elasticsearch和数据缓存)
第八章 安全控制(包含Spring Security和OAuth2)
第九章 响应式编程(包含Project Reactor、Spring WebFlux、Reactive NoSQL、R2DBC、Reactive Spring Security)
第十章 事件驱动(包含JMS、RabbitMQ、Kafka、Websocket、RSocket)
第11章 系统集成和批处理(包含Spring Integration和Spring Batch)
第12章 Spring Cloud与微服务
第13章 Kubernetes与微服务(包含Kubernetes、Helm、Jenkins、Istio)
多谢大家支持。

猜你喜欢

转载自blog.csdn.net/wiselyman/article/details/106894835