授权_封装权限信息
- 一、权限系统的作用
- 二、授权基本流程
- 三、限制访问资源所需权限
- 四、封装权限信息
- 4.1 权限信息封装到LoginUser
- 4.2 LoginUser 添加权限
- 4.3 过滤器封装权限信息
- 五、断点测试
- 5.1 有权限的访问
- 5.2 没有权限的访问
- 一键三连有没有捏~~
一、权限系统的作用
例如一个学校图书馆的管理系统,如果是普通学生登录就能看到借书还书相关的功能,不可能让他看到并且去使用添加书籍信息,删除书籍信息等功能。但是如果是一个图书馆管理员的账号登录了,应该就能看到并使用添加书籍信息,删除书籍信息等功能。
总结起来就是不同的用户可以使用不同的功能。这就是权限系统要去实现的效果。
我们不能只依赖前端去判断用户的权限来选择显示哪些菜单哪些按钮。因为如果只是这样,如果有人知道了对应功能的接口地址就可以不通过前端,直接去发送请求来实现相关功能操作。
所以我们还需要在后台进行用户权限的判断,判断当前用户是否有相应的权限,必须具有所需权限才能进行相应的操作
二、授权基本流程
授权的流程:
在SpringSecurity中,会使用默认的FilterSecurityInterceptor来进行权限校验。在FilterSecurityInterceptor中会从SecurityContextHolder获取其中的Authentication,然后获取其中的权限信息。当前用户是否拥有访问当前资源所需的权限。
所以我们在项目中只需要把当前登录用户的权限信息也存入Authentication。
然后设置我们的资源所需要的权限即可。
代码详细过程:
1、就是在我们之前的 UserDetailsServiceImpl 查询权限信息,添加到LoginUser中。
2、然后在LoginServiceImpl中通过Authentication就可以获取到权限信息了。
3、在JwtAuthenticationTokenFilter就可以将权限信息存入Authentication中了。然后就可以获取了。
三、限制访问资源所需权限
如何设置资源访问所需的权限:
有两种方式,一种是注解,一种是配置
实际上项目中用的都是基于注解的形式配置方式,基于配置方式的主要是用来配置静态资源,而前后端分离,就没有什么静态资源了,所以用的都是注解。
SpringSecurity为我们提供了基于注解的权限控制方案,这也是我们项目中主要采用的方式。我们可以
使用注解去指定访问对应的资源所需的权限。
但是要使用它我们需要先开启相关配置。
然后就可以使用对应的注解。@PreAuthorize
只能拥有test权限才可以访问
四、封装权限信息
我们前面在写UserDetailsServiceImpl的时候说过,在查询出用户后还要获取对应的权限信息,封装到UserDetails中返回。
我们先直接把权限信息写死封装到UserDetails中进行测试。
我们之前定义了UserDetails的实现类LoginUser,想要让其能封装权限信息就要对其进行修改。
4.1 权限信息封装到LoginUser
LoginUser修改完后我们就可以在UserDetailsServiceImpl中去把权限信息封装到LoginUser中了。我们写死权限进行测试,后面我们再从数据库中查询权限信息
这里先写死进行测试
4.2 LoginUser 添加权限
在security中,它去获取权限信息的时候,是调用UserDetails接口中的getAuthorities方法
所以我们要重写getAuthorities这个方法
重写getAuthorities方法,有两种写法
有一个需要一定注意的点:权限参数命名必须是authorities
第一种写法:传统
//存储SpringSecurity所需要的权限信息的集合
//@JSONField注解的作用是,进行序列化的忽略,这个变量不要序列化
@JSONField(serialize = false)
private List<GrantedAuthority> authorities;
//在security中,它去获取权限信息的时候,是调用UserDetails接口中的getAuthorities方法
//所以我们要重写getAuthorities这个方法,
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
if(authorities!=null){
return authorities;
}
//把permissions中字符串类型的权限信息转换成GrantedAuthority对象存入authorities中
for (String permission : permissions) {
SimpleGrantedAuthority authority = new SimpleGrantedAuthority(permission);
authorities.add(authority);
}
return authorities;
}
第二种写法:使用stream流,链式编程
//存储SpringSecurity所需要的权限信息的集合
//@JSONField注解的作用是,进行序列化的忽略,这个变量不要序列化
@JSONField(serialize = false)
private List<GrantedAuthority> authorities;
//在security中,它去获取权限信息的时候,是调用UserDetails接口中的getAuthorities方法
//所以我们要重写getAuthorities这个方法,
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
if(authorities!=null){
return authorities;
}
//把permissions中字符串类型的权限信息转换成GrantedAuthority对象存入authorities中
authorities = permissions.stream().
map(SimpleGrantedAuthority::new).
collect(Collectors.toList());
return authorities;
}
4.3 过滤器封装权限信息
五、断点测试
断点1
断点2
5.1 有权限的访问
先正常登录一下,然后访问hello接口
就进到了断点里面,看一下用户具有哪些权限,有test跟admin权限,可以访问
全部放行
5.2 没有权限的访问
修改一下helloController用户所拥有的权限
然后重启,重新登录再测试一下,它并不具备test333这个权限
全部放行,看一下,无权限,访问就是403