当前位置: 首页 > 科技观察

SpringSecurity中的四种权限控制方法

时间:2023-03-12 09:31:36 科技观察

松哥也为最近连载的SpringSecurity系列录制了视频教程。感兴趣的请点击这里->SpringBoot+Vue+微人视频教程(SpringBoot第十章为SpringSecurity)。SpringSecurity默认已经提供了很多权限控制,但是一个优秀的框架一定要有很好的扩展性。恰好SpringSecurity的扩展性非常好。我们可以使用SpringSecurity提供的方法进行授权,也可以自定义授权逻辑。总之一句话,想怎么玩就怎么玩!今天宋哥就给大家介绍一下SpringSecurity中四种常见的权限控制方式。表达式控制URL路径权限表达式控制方法权限使用过滤器注解动态权限四种方式,我们分别来看。1、表达式控制URL路径权限首先我们来看第一种方法,即通过表达式控制URL路径权限。松哥其实在之前的文章中讲过这个方法,这里我们稍微回顾一下。SpringSecurity支持在URL和方法权限控制中使用SpEL表达式。如果表达式的返回值为真,则表示需要相应的权限,否则表示不需要相应的权限。提供表达式的类是SecurityExpressionRoot:可以看到,SecurityExpressionRoot有两个实现类,分别代表SpEL在处理URL权限控制和方法权限控制时的扩展,比如在做基于URL路径的权限控制时,添加了hasIpAddress选项。让我们看一下SecurityExpressionRoot类中定义的最基本的SpEL:如您所见,这些是该类对应的表达式。我给大家解释一下这些表达方式:这是最基本的,在它的继承类中,还有一些扩展,就不重复介绍了。如果通过URL来控制权限,那么我们只需要配置如下:("/user/**").hasAnyRole("admin","user").anyRequest().authenticated().and()...}这里表示访问路径需要admin角色在/admin/**格式中,访问/user/**格式的路径需要管理员或用户角色。2、表达式控制方法权限当然我们也可以通过给方法加上注解来控制权限。为方法添加注解控制权限,我们需要先开启注解的使用,在SpringSecurity配置类中添加如下内容:@Configuration@EnableGlobalMethodSecurity(prePostEnabled=true,securedEnabled=true)publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{...}This配置开启三个注解,分别是:@PreAuthorize:方法执行前检查权限@PostAuthorize:方法执行后检查权限@Secured:类似@PreAuthorize,结合SpEL后,使用非常灵活,这里分享给大家你有点几个演示。@ServicepublicclassHelloService{@PreAuthorize("principal.username.equals('javaboy')")publicStringhello(){return"hello";}@PreAuthorize("hasRole('admin')")publicStringadmin(){return"admin";}@Secured({"ROLE_user"})publicStringuser(){return"user";}@PreAuthorize("#age>98")publicStringgetAge(Integerage){returnString.valueOf(age);}}第一个hello方法,注释的约束是只有当前以javaboy身份登录的用户才能访问此方法。第二个admin方法意味着访问此方法的用户必须具有admin角色。第三个用户方法表示该方法的用户必须有用户角色,但是注意用户角色需要加上ROLE_前缀。第四个getAge方法表示访问该方法的age参数必须大于98,否则请求不通过。可以看出这里的表情还是很丰富的。如果要引用方法的参数,只要在前面加一个#即可。可以参考基本类型的参数,也可以参考对象参数。除了principal,defaultobject还有authentication(参考第一节)。3、使用过滤注解SpringSecurity中还有@PreFilter和@PostFilter这两个过滤函数,可以根据给定的条件自动移除集合中的元素。@PostFilter("filterObject.lastIndexOf('2')!=-1")publicListgetAllUser(){Listusers=newArrayList<>();for(inti=0;i<10;i++){users.add("javaboy:"+i);}returnusers;}@PreFilter(filterTarget="ages",value="filterObject%2==0")publicvoidgetAllAge(Listages,Listusers){System.out.println("ages="+ages);System.out.println("users="+users);}在getAllUser方法中,过滤集合,只返回后缀为2的元素,filterObject表示要过滤的元素的对象。在getAllAge方法中,由于有两个集合,所以使用filterTarget来指定过滤对象。4.动态权限动态权限主要是通过重写拦截器和决策器来实现的。这个我在vhr文档里有详细介绍。可以在公众号【江南一点鱼】后台回复888获取文档,我就不多说了。5.总结好了,今天就和小伙伴们聊一聊SpringSecurity中的授权问题。当然,这里还有很多细节。稍后宋哥会一一跟大家说。本文转载自微信公众号“江南的一场小雨”,可通过以下二维码关注。转载本文请联系江南一点鱼公众号。