Spring Security权限管理原理

news/2024/4/25 21:00:30/文章来源:https://blog.csdn.net/qq_39385118/article/details/128099805

1.简介

授权是更具系统提前设置好的规则,给用户分配可以访问某一资源的权限,用户根据自己所具有的权限,去执行相应的操作,spring security提供的权限管理功能主要有两种:

  • 基于过滤器的权限管理功能(FilterSecurityInterceptor)
  • 基于AOP的权限管理功能(MethodSecurityInterceptor)

2. 核心概念

2.1 角色与权限

用户信息都保存在Authentication信息中,Authentication对象中有一个Collection<? extends GrantedAuthority> getAuthorities()  当需要进行鉴权时,就会调用该方法获取用户权限,进而做出判断。无论用户采取何种认证方式,都不影响授权。

从设计层面来讲,角色和权限是两个完全不同的东西,权限是一些具体操作,例如read、write,角色则是某些权限的集合,例如管理员、普通用户。

从代码层面讲,角色和权限并没有太大的不同。

至于Collection<? extends GrantedAuthority> getAuthorities() 的返回值,需要分情况对待:

(1) 如果权限系统设计的比较简单,用户<==>权限<==>资源三者之间的关系,那么getAuthorities就是返回用户的权限

(2) 如果权限系统设计的比较复杂,如用户<==>角色<==>权限<==>资源,此时将getAuthorities的返回值当作权限来理解。由于Spring Security并未提供相关的角色类,因此此时需要我们自定义角色类。

1

2

3

4

5

6

7

8

9

10

public class Role implements GrantedAuthority{

private String name;

private List<SimpleGrantedAuthority> allowedOperations=new ArrayList<>();

@Override

public String getAuthority{

 return name;

}

省略getter/setter方法

}

角色继承自GrantedAuthority,一个角色对应多个权限,然后在定义用户类的时候,将角色转为权限即可.

1

2

3

4

5

6

7

8

9

10

11

12

13

public class User implements UserDetails{

private List<Role> roles=new ArrayList<>();

@Override

public Collection<? extends GrantedAuthority> getAuthorities(){

List<SimpleGrantedAuthority> authorities=new ArrayList<>();

for(Role role:roles){

 authorities.addAll(role.getAllowedOperations());

}

return authorities.stream().distinct().collect(Collectors.toList());

}

省略getter/setter方法

}

2.2 角色继承

指角色存在一个上下级关系,例如ADMIN继承自USER,那么ADMIN就自动具备USER的所有权限。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

public interface RoleHierarchy {

    /**

     * Returns an array of all reachable authorities.

     * <p>

     * Reachable authorities are the directly assigned authorities plus all authorities

     * that are (transitively) reachable from them in the role hierarchy.

     * <p>

     * Example:<br>

     * Role hierarchy: ROLE_A > ROLE_B > ROLE_C.<br>

     * Directly assigned authority: ROLE_A.<br>

     * Reachable authorities: ROLE_A, ROLE_B, ROLE_C.

     * @param authorities - List of the directly assigned authorities.

     * @return List of all reachable authorities given the assigned authorities.

     */

    Collection<? extends GrantedAuthority> getReachableGrantedAuthorities(

            Collection<? extends GrantedAuthority> authorities);

}

2.3 FilterSecurityInterceptor处理器

基于过滤器的权限过滤器(FilterSecurityInterceptor)有一个前置过滤器和后置过滤器,首先由前置处理器判断发起当前请求的用户是否具备相应的权限,如果具备则请求继续向下走,到达目标方法并执行完毕。在相应时,会经过FilterSecurityInterceptor,次吃由后置处理器再去完成收尾工作(后置过滤器一般不工作),如图2-3所示。

图2-3

2.4 前置过滤器

前置过滤器主要有两个核心组件,分别是投票器和决策器。

2.4.1 投票器

当投票器在投票时,需要两方面的权限:其一是当前用户具备哪些权限;其二是当前访问的URL需要哪些权限才能访问,投票器就是对这两种权限进行比较。其接口如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

/**

 * Indicates a class is responsible for voting on authorization decisions.

 * <p>

 * The coordination of voting (ie polling {@code AccessDecisionVoter}s, tallying their

 * responses, and making the final authorization decision) is performed by an

 * {@link org.springframework.security.access.AccessDecisionManager}.

 *

 * @author Ben Alex

 */

public interface AccessDecisionVoter<S> {

    //同意

    int ACCESS_GRANTED = 1;

    //放弃

    int ACCESS_ABSTAIN = 0;

    //拒绝

    int ACCESS_DENIED = -1;

    //用来判断是否支持ConfigAttribute对象

    boolean supports(ConfigAttribute attribute);

    //用来判断是否支持受保护的安全对象

    boolean supports(Class<?> clazz);

    //具体投票方法,authentication可以提取出当前用户具备的权限;object表示受保护的安全对象,是一个FilterInvocation实例;attributes表示访问受保护对象所需的权限。返回值就是-1/0/1

  int vote(Authentication authentication, S object, Collection<ConfigAttribute> attributes);

}

AccessDecisionVoter常用的实现类如下图2-4-1所示,本项目中主要用到RoleVoter和RoleHierarchyVoter。

RoleVoter:RoleVoter是根据登陆主体的角色进行投票,即判断当前用户是否具备受保护对象所需要的角色。需要注意的是,默认情况下,角色需要以ROLE_开始,否则supports方法会直接返回false。

RoleHierarchyVoter:继承自RoleVoter,投票逻辑和RoleVoter一样,不同的是RoleHierarchyVoter支持角色的继承,它通过RoleHierarchyImpl对象对用户所具有的角色进行解析,获得用户真正可触达的角色,而RoleVoter则直接调用 authentication.getAuthorities()方法获得用户的角色。

图2-4-1

2.4.2 决策器

决策器由AccessDecisionManager负责,AccessDecisionManager会同时管理多个投票器,由AccessDecisionManager调用投票器进行投票,然后根据投票结果做出相应的决策。

1

2

3

4

5

6

7

8

9

public interface AccessDecisionManager {

    void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)

            throws AccessDeniedException, InsufficientAuthenticationException;

    boolean supports(ConfigAttribute attribute);

    boolean supports(Class<?> clazz);

}

decide方法:是核心的决策方法,在这个方法中判断是否允许当前URL调用, 如果拒绝访问的话会抛出AccessDeniedException异常。

supports(ConfigAttribute) 方法:用来判断是否支持ConfigAttribute对象。

supports(Class)方法:用来判断是否支持当前安全对象。

和决策器相关的类关系,如图2-4-2所示,AccessDecisionManager会同时管理多个投票器,由AccessDecisionManager调用投票器进行投票,然后根据投票结果做出相应的决策,有一个抽象实现类AbstractAccessDecisionManager,AbstractAccessDecisionManager一共有三个子类:
AffirmativeBased:一票通过机制(默认即此)
ConsensusBased:少数服从多数机制,平局的话,则看 allowIfEqualGrantedDeniedDecisions 参数的取值
UnanimousBased:一票否决制


 

图2-4-2

2.5 权限元数据

2.5.1 ConfigAttribute

在介绍投票器的时候,在具体的投票方法vote中,受保护的对象所需要的权限保存在一个Collection集合中,集合中的对象是ConfigAttribute而不是GrantedAuthority,ConfigAttribute用来存储与安全系统相关的配置属性,也就是系统关于权限的配置,接口如下:

1

2

3

public interface ConfigAttribute extends Serializable{

 String getAttribute();

}

 

只有一个getAttribute方法返回具体的权限字符串,而GrantedAuthority则是通过getAuthority方法返回用户所具有的权限,随着两个类不同,但是二者的返回值都是字符串是可以比较的。其部分实现类如图2-5-1所示。

图2-5-1

2.5.2 SecurityMetadataSource

提供受保护的对象所需的权限,例如,用户访问了一个URL地址需要哪些权限才能访问?这个就由SecurityMetadataSource提供

3. 基于URL地址的权限管理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_38767.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python学习笔记-数字类型

目录 1. 数字类型 1.1 整型 1.2 浮点数 1.3 复数 1.4 布尔类型 2. 常用内置数值计算函数库 3. 随机数函数 本文记录python中的基本数字类型信息&#xff0c;以及一些其他的相关知识点。 1. 数字类型 python中用于标识数字或者数值的数据类型&#xff0c;主要有如下分类…

盘点程序员的花式赚外快的骚操作

2022世界杯比赛难得如期开幕了&#xff0c;卡塔尔王子的表情包想必大家已经看到眼晕。 我拿2200亿和你玩&#xff0c;你踢一个0&#xff1a;2过不过分啊~ 现实中的投资可不比卡塔尔王子的表情包失落更多&#xff0c;毕竟投资有风险入行需谨慎。 然而悲惨的事实是&#xff0c;…

量表如何分析?

一、什么是量表 量表是一种测量工具&#xff0c;通常用来测量人们的主观态度、意见或价值观念。我们经常会在问卷中使用量表对调查对象进行测量&#xff0c;最常见到的就是李克特量表。 ‍1、定义&#xff1a;李克特量表 李克特量表是最常用的量表&#xff0c;是由美国社会心…

大数据平台功能

一 前言 计算机设备和信息数据的相互融合&#xff0c;对各个行业来说都是一次非常大的进步&#xff0c;已经渗入到工业、农业、商业、军事等领域&#xff0c;同时其大数据平台软件也得到一定发展。就目前来看&#xff0c;各类编程语言的发展、人工智能相关算法的应用、大数据时…

求树的直径算法以及证明

以下为两次dfs&#xff08;bfs&#xff09;的做法以及正确性证明。 算法步骤 &#xff08;1&#xff09;任取树上一点S&#xff0c;以S为源点BFS得S到各个顶点的d值&#xff1b; &#xff08;2&#xff09;取d值最大者之一为P&#xff0c;再以P为源点BFS得P到各个顶点的d值&am…

【计算机】可信平台模块Trusted Platform Module - TPM

简述 Brief Introduction TPM内部功能模块示意图&#xff1a; 引述 Trusted Platform Module Technology Overview (Windows) | Microsoft Learn&#xff1a; Trusted Platform Module (TPM) technology is designed to provide hardware-based, security-related functions.…

「区块链+数字身份」:DID 身份认证的新战场

美国经济学家布莱恩 • 阿瑟在其著作《技术的本质》中&#xff0c;写过这么一句话&#xff1a;「技术总是进行着这样一种循环&#xff0c;为解决老问题去采用新技术&#xff0c;新技术又引发新问题&#xff0c;新问题的解决又要诉诸更新的技术」。 区块链技术之所以能流行&…

在MacOS上实现两个网络调试助手的UDP通信测试

文章目录一、背景二、网络调试助手软件三、UDP通信过程一、背景 因为有一个项目要中会使用本机中两个应用程序之间的UDP通信。 因此本文记录一下怎么在MacOS上实现两个网络调试助手的UDP通信测试。 二、网络调试助手软件 我使用的网络调试助手软件是&#xff1a;网络调试助…

Redis实战——优惠券秒杀(超卖问题)

1 实现优惠券秒杀功能 下单时需要判断两点&#xff1a;1.秒杀是否开始或者结束2.库存是否充足 所以&#xff0c;我们的业务逻辑如下 1. 通过优惠券id获取优惠券信息 2.判断秒杀是否开始&#xff0c;如果未返回错误信息 3.判断秒杀是否结束&#xff0c;如果已经结束返回错误…

传奇登录器打不开的四种原因

最近很多传奇玩家或者GM都遇到了传奇登陆器打不开&#xff0c;没反应&#xff0c;提示无法访问指定设备等问题&#xff0c;导致很多游戏没有办法玩&#xff0c;让玩家心情沮丧&#xff0c;作为GM&#xff0c;那么就更伤心了&#xff0c;很多玩家进不来游戏&#xff0c;开服数千…

Maven笔记(2022-11-29)

一、Maven简述 1.1 什么是Maven&#xff1f; Apache Maven 是一款基于 Java 平台的项目管理和构建工具&#xff0c;它基于项目对象模型(POM)的概念&#xff0c;通过一小段描述信息来管理项目的构建、报告和文档。 简单来讲Maven就是一个构建工具&#xff0c;用来管理我们的项目…

GMM算法

高斯混合模型聚类(Gaussian Mixture Mode&#xff0c;GMM) 高斯混合模型是一种概率式的聚类方法&#xff0c;它假定所有的数据样本x由k个混合多元高斯分布组合成的混合分布生成。 其中高斯分布的概率密度函数如下&#xff1a; 现在的问题就是如何求α,μ,σ\alpha,\mu,\sigm…

Spring-全面详解(学习总结---从入门到深化)

目录 Spring简介 Spring体系结构 IOC_控制反转思想 IOC_自定义对象容器 IOC_Spring实现IOC IOC_Spring容器类型 ​ 容器实现类 IOC_对象的创建方式 使用构造方法 使用工厂类的方法…

09【MyBatis多表关联查询】

文章目录三、MyBatis多表关联查询3.1 表的关系3.2 一对一查询3.2.1 搭建环境3.2.2 需求分析3.2.3 dao接口3.2.3 mapper.xml3.2.4 测试3.2.5 配置MyBatis一对一关系1&#xff09;传统映射&#xff1a;2&#xff09;使用association标签映射3.3 一对多查询3.3.1 需求分析3.3.2 da…

Kamiya丨Kamiya艾美捷大鼠微量白蛋白酶联免疫吸附试验说明书

Kamiya艾美捷大鼠微量白蛋白酶联免疫吸附试验预期用途&#xff1a; 大鼠微量白蛋白酶联免疫吸附试验&#xff08;ELISA&#xff09;是一种高灵敏度的双位点酶联免疫吸附试验&#xff08;ELISA&#xff09;大鼠生物样品中微量白蛋白的测定。仅供研究使用。 引言 白蛋白&#x…

SpringBoot、EasyPoi、Echarts 实现文档导入、出、图表显示 (饼状图、柱状图) 保姆级教程

一、介绍环境 EasyPOI: 现在我们就来介绍下EasyPoi,首先感谢EasyPoi 的开发者​。EasyPoi开源 easypoi 是为了让开发者快速的实现excel&#xff0c;word,pdf的导入导出&#xff0c;基于Apache poi基础上的一个工具包。easypoi教程 Echarts: …

转扩!寻找G2022次列车“旅客”

各位求职朋友大家好&#xff0c;欢迎乘坐G2022次列车 本次列车为6节编组&#xff0c;由上海开往北京&#xff0c;途径宁波、重庆 本次列车乘务组全体工作人员为您提供全方位福利待遇 上车地址&#xff1a;上海擎创信息技术有限公司 - 社会招聘 (eoitek.com) 如您还需其他帮助…

Java给图片增加水印,根据图片大小自适应,右下角/斜角/平铺

Hi&#xff0c;I’m Shendi 最近写自己的文件服务器&#xff0c;上传图片时需要自动增加水印&#xff0c;在这里记录一下 文章目录效果展示读取图片从 byte[] 读取图片获取画板绘制水印根据图片大小自适应水印大小右下角文字水印斜角水印平铺水印图片水印输出图片水印就是在图片…

SLAM学习笔记(二)

5.相机与图像 相机将三维世界中的坐标点&#xff08;单位米&#xff09;映射到二维图像平面&#xff08;单位为像素&#xff09;的过程中能够用一个几何模型进行描述。 单目相机(Mono)的成像过程&#xff1a; 1、世界坐标系下有个固定的点P&#xff0c;世界坐标为 2、由于相…

基于Java+SSM+Vue+ElementUi的汉语言类网上考试系统

项目介绍 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信…