您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~

之前虽然实现了角色和权限之间的简单配对,但是如果每一个角色都要重新来过一次,就有点呆板了。如果能够配置一个「角色模板」,再通过这个模板来配置其他角色,岂不是更简单?Spring Security虽然没有角色模板,但可以通过「继承」的方式来「曲线就国」。

而且有时候角色与用户并不是完全一一对应的。比如,admin接口只有ROLE_ADMIN角色拥有,manager接口只有ROLE_MANAGER角色拥有。但其实admin是应该拥有manager的权限的。所以来看看怎么个「应该」法。

首先,在sys_suer表中增加employee用户:

INSERT INTO sys_user VALUES (3, 'employee', '123456', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);

然后在sys_role表中增加ROLE_EMPLOYEE角色:

INSERT INTO sys_role VALUES (3, 'ROLE_EMPLOYEE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);

再在sys_permission权限表中增加角色权限:

INSERT INTO sys_permission VALUES (5,3,'/employee','read',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP);

INSERT INTO sys_permission VALUES (6,3,'/employee','remove',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP);

修改LoginController,增加employee接口:

@GetMapping("/admin")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public String admin() {
return "admin有ROLE_ADMIN角色";
} @GetMapping("/manager")
@PreAuthorize("hasRole('ROLE_MANAGER')")
public String manager() {
return "manager有ROLE_MANAGER角色";
} @GetMapping("/employee")
@PreAuthorize("hasRole('ROLE_EMPLOYEE')")
public String employee() {
return "employee有ROLE_EMPLOYEE角色";
}

然后在WebSecurityConfiguration中引入Spring Security的RoleHierarchy角色继承类:

// 角色继承
@Bean
public RoleHierarchy roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
// 多个角色用【>】表示,【>】左边角色的权限要大于右边角色的权限
String hierarchy = "ROLE_ADMIN > ROLE_MANAGER " + System.lineSeparator() +
" ROLE_MANAGER > ROLE_EMPLOYEE";
// 也可以写成 "ROLE_ADMIN > ROLE_MANAGER > ROLE_EMPLOYEE";
roleHierarchy.setHierarchy(hierarchy);
return roleHierarchy;
}

通过Postman测试用户各自拥有的角色:

1、admin { ROLE_ADMIN, ROLE_MANAGER, ROLE_EMPLOYEE }

2、manager { ROLE_MANAGER, ROLE_EMPLOYEE }

3、employee { ROLE_EMPLOYEE }

可以看出来,Spring Security有几个特点:

1、角色可以被继承,但权限并不能“跟随”角色一起被继承

2、admin只能访问/admin/create和/admin/read这两个接口

3、manager也只能访问/manager/create和/manager/remove这两个接口

4、admin虽然继承了user的角色ROLE_MANAGER,但并没有显示地获得ROLE_MANAGER对应的权限,因为加入权限后,角色继承就会失效

因为权限无法跟随角色被继承,所以需要手动去完善权限。为了让admin也能访问manager的接口,要赋予角色更多的权限。现在把manager和employee的权限都赋予admin:

INSERT INTO sys_permission VALUES (7,1,'/manager','create',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP);

INSERT INTO sys_permission VALUES (8,1,'/manager','remove',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP);

INSERT INTO sys_permission VALUES (9,1,'/employee','read',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP);

INSERT INTO sys_permission VALUES (10,1,'/employee','remove',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP);

然后在LoginController里再增加employee的权限:

@GetMapping("/employee/read")
@PreAuthorize("hasPermission('/employee', 'read')")
public String employeeRead() {
return "employee有ROLE_EMPLOYEE角色的read权限";
} @GetMapping("/employee/remove")
@PreAuthorize("hasPermission('/employee', 'remove')")
public String employeeRemove() {
return "employee有ROLE_EMPLOYEE角色的remove权限";
}

通过admin登录,分别访问如下接口:

可以看到,admin已经有之前manager和employee的权限了。

Spring Security虽然比较简单,也很方便,多适用于一些比较小型的应用系统,角色简单,权限不多。如果要实现一些比较复杂的权限功能,Spring Security就会有点力不从心了,而且会出现诸如自定义filter被执行多次的问题。所以,一般在大型或企业级应用中,都不会,至少不会完全依赖Spring Security,而是依据实际业务需求,实现自定义的权限系统。


感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~

Spring Security(8)的更多相关文章

  1. Spring Security(08)——intercept-url配置

    http://elim.iteye.com/blog/2161056 Spring Security(08)--intercept-url配置 博客分类: spring Security Spring ...

  2. Spring Security(三)

    Spring Security(三) 个性化用户认证流程 自定义登录页面 在配置类中指定登录页面和接收登录的 url @Configuration public class BrowserSecuri ...

  3. Spring Security(二)

    Spring Security(二) 注:凡是源码部分,我已经把英文注释去掉了,有兴趣的同学可以在自己项目里进去看看.:-) 定义用户认证逻辑 用户登录成功后,用户的信息会被 Security 封装在 ...

  4. Spring Security(一)

    Spring Security(一) 基本原理 前言 Spring Security核心功能 认证(你是谁) 授权(你能干什么) 攻击防护(防止伪造身份) Srping Security基本原理 项目 ...

  5. 【权限管理系统】Spring security(三)---认证过程(原理解析,demo)

      在前面两节Spring security (一)架构框架-Component.Service.Filter分析和Spring Security(二)--WebSecurityConfigurer配 ...

  6. SpringBoot集成Spring Security(7)——认证流程

    文章目录 一.认证流程 二.多个请求共享认证信息 三.获取用户认证信息 在前面的六章中,介绍了 Spring Security 的基础使用,在继续深入向下的学习前,有必要理解清楚 Spring Sec ...

  7. SpringBoot集成Spring Security(6)——登录管理

    文章目录 一.自定义认证成功.失败处理 1.1 CustomAuthenticationSuccessHandler 1.2 CustomAuthenticationFailureHandler 1. ...

  8. SpringBoot集成Spring Security(5)——权限控制

    在第一篇中,我们说过,用户<–>角色<–>权限三层中,暂时不考虑权限,在这一篇,是时候把它完成了. 为了方便演示,这里的权限只是对角色赋予权限,也就是说同一个角色的用户,权限是 ...

  9. SpringBoot集成Spring Security(4)——自定义表单登录

    通过前面三篇文章,你应该大致了解了 Spring Security 的流程.你应该发现了,真正的 login 请求是由 Spring Security 帮我们处理的,那么我们如何实现自定义表单登录呢, ...

  10. SpringBoot集成Spring Security(2)——自动登录

    在上一章:SpringBoot集成Spring Security(1)——入门程序中,我们实现了入门程序,本篇为该程序加上自动登录的功能. 文章目录 一.修改login.html二.两种实现方式 2. ...

随机推荐

  1. Elasticsearch Top10 监控指标

    文章转载自: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247484441&idx=1&sn=8292f50 ...

  2. Elasticsearch 集群健康值红色终极解决方案

    文章转载自: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247483905&idx=1&sn=acaff63 ...

  3. 04_第一个Java程序

    HelloWorld D盘下新建一个文件夹Java_work,存放代码 进入Java_work,新建一个Hello.java文件 文件后缀名为.java Hello.java 注意:系统可能没有显示文 ...

  4. day43-反射02

    2.Class类 2.1基本介绍 Class类也是类,因此也继承Object类 Class类对象不是new出来的,而是系统创建的 对于某个类的Class类对象,在内存中只有一份,因为类只加载一次 每个 ...

  5. DateSet的应用

    一.知识描述 1.什么是DataSet? DataSet为一个数据集,可以看做是一个内存中的数据库,包括表.数据行.数据列以及表与表之间的关系. 创建一个DataSet后,它可以单独存在,不需要一直保 ...

  6. 虚拟线程 - VirtualThread源码透视

    前提 JDK19于2022-09-20发布GA版本,该版本提供了虚拟线程的预览功能.下载JDK19之后翻看了一下有关虚拟线程的一些源码,跟早些时候的Loom项目构建版本基本并没有很大出入,也跟第三方J ...

  7. cifar-10-dataset

    import cv2 import numpy as np import os import pickle data_dir = os.path.join("data", &quo ...

  8. 代码随想录第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

    2022/09/22 第二天 第一题 这题我就直接平方后排序了,很无脑但很快乐啊(官方题解是双指针 第二题 滑动窗口的问题,本来我也是直接暴力求解发现在leetCode上超时,看了官方题解,也是第一次 ...

  9. 解决在JS中阻止定时器“重复”开启问题、Vue中定时器的使用

    1.问题描述 在一些需求开发中.需要设定软件提供服务的时间段(营业时间).这时可以选择定时器来实现.可以选择让定时器每隔一段时间检测当前时间是否在服务时间.到达服务时间.进入服务状态.未到服务时间.进 ...

  10. 齐博x1标签实例:做模板组图单图无图混排的处理

    代码如下, {qb:tag name="xxx" type="cms" rows="10"} {if ( count($rs['picurl ...