Spring Security 中的四种权限控制方式

开发 前端
Spring Security 中对于权限控制默认已经提供了很多了,但是,一个优秀的框架必须具备良好的扩展性,恰好,Spring Security 的扩展性就非常棒,我们既可以使用 Spring Security 提供的方式做授权,也可以自定义授权逻辑。

 松哥给最近连载的 Spring Security 系列也录制了视频教程,感兴趣的小伙伴请戳这里->Spring Boot+Vue+微人事视频教程(Spring Boot 第十章就是 Spring Security)。

Spring Security 中对于权限控制默认已经提供了很多了,但是,一个优秀的框架必须具备良好的扩展性,恰好,Spring Security 的扩展性就非常棒,我们既可以使用 Spring Security 提供的方式做授权,也可以自定义授权逻辑。一句话,你想怎么玩都可以!

今天松哥来和大家介绍一下 Spring Security 中四种常见的权限控制方式。

  • 表达式控制 URL 路径权限
  • 表达式控制方法权限
  • 使用过滤注解
  • 动态权限

四种方式,我们分别来看。

1.表达式控制 URL 路径权限

首先我们来看第一种,就是通过表达式控制 URL 路径权限,这种方式松哥在之前的文章中实际上和大家讲过,这里我们再来稍微复习一下。

Spring Security 支持在 URL 和方法权限控制时使用 SpEL 表达式,如果表达式返回值为 true 则表示需要对应的权限,否则表示不需要对应的权限。提供表达式的类是 SecurityExpressionRoot:

 

可以看到,SecurityExpressionRoot 有两个实现类,表示在应对 URL 权限控制和应对方法权限控制时,分别对 SpEL 所做的拓展,例如在基于 URL 路径做权限控制时,增加了 hasIpAddress 选项。

我们来看下 SecurityExpressionRoot 类中定义的最基本的 SpEL 有哪些:

可以看到,这些都是该类对应的表达式,这些表达式我来给大家稍微解释下:

这是最基本的,在它的继承类中,还有做一些拓展,我这个我就不重复介绍了。

如果是通过 URL 进行权限控制,那么我们只需要按照如下方式配置即可:

  1. protected void configure(HttpSecurity http) throws Exception { 
  2.     http.authorizeRequests() 
  3.             .antMatchers("/admin/**").hasRole("admin"
  4.             .antMatchers("/user/**").hasAnyRole("admin""user"
  5.             .anyRequest().authenticated() 
  6.             .and() 
  7.             ... 

这里表示访问 /admin/** 格式的路径需要 admin 角色,访问/user/** 格式的路径需要 admin 或者 user 角色。

2.表达式控制方法权限

当然,我们也可以通过在方法上添加注解来控制权限。

在方法上添加注解控制权限,需要我们首先开启注解的使用,在 Spring Security 配置类上添加如下内容:

  1. @Configuration 
  2. @EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true
  3. public class SecurityConfig extends WebSecurityConfigurerAdapter { 
  4.     ... 
  5.     ... 

这个配置开启了三个注解,分别是:

  • @PreAuthorize:方法执行前进行权限检查
  • @PostAuthorize:方法执行后进行权限检查
  • @Secured:类似于 @PreAuthorize

这三个结合 SpEL 之后,用法非常灵活,这里和大家稍微分享几个 Demo。

  1. @Service 
  2. public class HelloService { 
  3.     @PreAuthorize("principal.username.equals('javaboy')"
  4.     public String hello() { 
  5.         return "hello"
  6.     } 
  7.  
  8.     @PreAuthorize("hasRole('admin')"
  9.     public String admin() { 
  10.         return "admin"
  11.     } 
  12.  
  13.     @Secured({"ROLE_user"}) 
  14.     public String user() { 
  15.         return "user"
  16.     } 
  17.  
  18.     @PreAuthorize("#age>98"
  19.     public String getAge(Integer age) { 
  20.         return String.valueOf(age); 
  21.     } 
  1. 第一个 hello 方法,注解的约束是,只有当前登录用户名为 javaboy 的用户才可以访问该方法。
  2. 第二个 admin 方法,表示访问该方法的用户必须具备 admin 角色。
  3. 第三个 user 方法,表示方法该方法的用户必须具备 user 角色,但是注意 user 角色需要加上ROLE_ 前缀。
  4. 第四个 getAge 方法,表示访问该方法的 age 参数必须大于 98,否则请求不予通过。

可以看到,这里的表达式还是非常丰富,如果想引用方法的参数,前面加上一个# 即可,既可以引用基本类型的参数,也可以引用对象参数。

缺省对象除了 principal ,还有 authentication(参考第一小节)。

3.使用过滤注解

Spring Security 中还有两个过滤函数 @PreFilter 和 @PostFilter,可以根据给出的条件,自动移除集合中的元素。

  1. @PostFilter("filterObject.lastIndexOf('2')!=-1"
  2. public List<String> getAllUser() { 
  3.     List<String> users = new ArrayList<>(); 
  4.     for (int i = 0; i < 10; i++) { 
  5.         users.add("javaboy:" + i); 
  6.     } 
  7.     return users; 
  8. @PreFilter(filterTarget = "ages",value = "filterObject%2==0"
  9. public void getAllAge(List<Integer> ages,List<String> users) { 
  10.     System.out.println("ages = " + ages); 
  11.     System.out.println("users = " + users); 

在 getAllUser 方法中,对集合进行过滤,只返回后缀为 2 的元素,filterObject 表示要过滤的元素对象。

在 getAllAge 方法中,由于有两个集合,因此使用 filterTarget 指定过滤对象。

4.动态权限

动态权限主要通过重写拦截器和决策器来实现,这个我在 vhr 的文档中有过详细介绍,大家在公众号【江南一点雨】后台回复 888 可以获取文档,我就不再赘述了。

5.小结

好啦,今天就喝小伙伴们稍微聊了一下 Spring Security 中的授权问题,当然这里还有很多细节,后面松哥再和大家一一细聊。

本文转载自微信公众号「江南一点雨」,可以通过以下二维码关注。转载本文请联系江南一点雨公众号。

 

责任编辑:武晓燕 来源: 江南一点雨
相关推荐

2021-07-27 10:49:10

SpringSecurity权限

2022-08-30 08:43:11

Spring权限控制

2023-05-22 08:03:28

JavaScrip枚举定义

2022-08-30 08:50:07

Spring权限控制

2022-08-15 08:45:21

Spring权限控制

2022-08-30 08:36:13

Spring权限控制

2022-08-15 08:42:46

权限控制Spring

2022-08-30 08:55:49

Spring权限控制

2022-03-25 14:47:24

Javascript数据类型开发

2010-07-28 13:54:42

Flex数据绑定

2017-04-17 19:31:03

Android多线程

2009-06-22 11:01:12

2009-06-11 17:22:03

操作xml方式Java

2020-06-12 08:28:29

JavaScript开发技术

2013-06-14 15:24:57

Android开发移动开发数据存储方式

2021-12-22 09:34:01

Golagn配置方式

2014-12-25 09:41:15

Android加载方式

2013-10-17 09:25:52

2022-03-15 11:01:39

KubernetesLinux平滑升级

2019-10-24 07:42:28

Java引用GC
点赞
收藏

51CTO技术栈公众号