SpringSecurity如何使用注解控制权限

首页 / 新闻资讯 / 正文

一般的系统在权限设计上,都会分为角色、权限(RDBC),复杂一点的可能会有用户组、组织之类的概念。

用户的权限是写死的,对应于后台的接口或者资源,是没办法改变的,一般不对用户开放修改权限。

管理员用户可以通过给角色分配权限的方式,来实现访问控制。

所以当我们写过滤器,或者用一些安全框架时(比如Shiro,Spring Security),也需要将可变的“角色”,转化为不可变的“权限”,注入到框架中。

具体的可以看我之前写的一篇(Spring Security整合jwt完整版):https://blog.csdn.net/qq_37855749/article/details/111300906

注入当前用户的权限后,就需要进行访问控制了。

常见的做法有

1、路径比对

之前有个项目用过一次,定义一个过滤器,添加到security的过滤链中,在这个过滤器中做这么一件事:

分析当前访问路径所需要的权限,检查当前用户是否具有该权限,做一个对比,根据对比结果来决定当前用户是否可以访问该资源。

这种做法的好处是代码的入侵性不高,不需要再每个接口上加注解。但相对来说,显得不那么直观,可读性比较差,所以这次换个方法。

2、使用注解的方式

SpringSecurity使用注解来控制访问时,需要提前开启这个功能。

在配置类上加上注解

@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter {

在接口中如此使用

    /**      * 条件查询      */     @PreAuthorize("hasAuthority('IMPORT:SELECT')")     @ApiOperation(value = "查询")     @GetMapping("/list")     public R<Page<Task>> list(TaskDto taskDto){         //测试阶段,随机生成任务         Random random = new Random();          //todo         int i = random.nextInt(4);         if(i == 2) {             metroServerAdapterService.reloadShelveTask();         }         Page<Task> list = taskService.list(taskDto);         return R.ok(list);     }

hasAuthority可以替换成hasRole,虽然可以达到相同的目的,但是在使用的方法上还是有些不同的。

hasRole要求内容必须以"ROLE_"开头,也是官方推荐的命名方式,否则没有效果。但是hasAuthority没有限制,数据库中怎样写的,代码里就怎么写。

同样的功能的注解为什么要有两个名字呢。或许这么做可能在语义上比较清晰明确一点,将角色与权限这两个概念稍加区分。

仔细想一下,确实有些小型的系统或许压根就不需要权限,只有给用户分配角色,没有给角色分配权限这一过程。这样的话,角色也是不可变的,就可以根据角色来做访问控制了。

但考虑通用性,个人觉得用hasAuthority就可以了。