【深入浅出Spring Security(一)】Spring Security的整体架构

news2025/1/11 5:42:10

Spring Security的整体架构

  • 一、整体架构
    • 认证(Authentication)
      • AuthenticationManager
      • Authentication
      • 登录后的数据保存(SecurityContextHolder)
    • 授权(Authorization)
      • ConfigAttribute
  • 二、总结

这篇博客所述主要是在读《深入浅出Spring Security》途中所做的笔记(之前有学Spring Security,但了解的比较浅,所以想着看这本书深入一点点,这都是因为上次一个bug调了我几天)

下面是这本书pdf的网盘链接,分享给大家(过期了的话,可私信获取)。

链接:https://pan.baidu.com/s/1hFNX93PUtnd-qUaI1CsX8A?pwd=sh1w
提取码:sh1w

一、整体架构

在 SpringSecurity 的架构设计中,认证(Authentication)和授权(Authorization)是分开的,无论使用什么样的认证方式,都不会影响授权,这是两个独立的存在,这种独立带来的好处之一,就是可以非常方便地整合一些外部的解决方案。下图是认证和授权所用到的核心接口(下面会分别进行解释):

在这里插入图片描述

认证(Authentication)

通俗地说,认证就是身份认证(你是谁?)

AuthenticationManager

在SpringSecurity中认证是由 AuthenticationManager 接口来负责的,接口定义为:

public interface AuthenticationManager {
    Authentication authenticate(Authentication authentication) throws AuthenticationException;
}
  • 返回 Authentication 表示认证成功;
  • 返回 AuthenticationException 异常,表示认证失败。

AuthenticationManager 主要实现类为 ProviderManager,在 ProviderManager 中管理了众多AuthenticationProvider 实例。在一次完整的认证流程中,SpringSecurity 允许存在多个AuthenticationProvider,用来实现多种认证方式,这些 AuthenticationProvider 都是由 ProviderManager 进行统一管理的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8AS17X0J-1685270725457)(C:\Users\myz03\AppData\Roaming\Typora\typora-user-images\image-20230528110420464.png)]

Authentication

认证以及认证成功的信息主要是由 Authentication 的实现类进行保存的,Authentication 接口的结构如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mAzjFNq5-1685270725457)(C:\Users\myz03\AppData\Roaming\Typora\typora-user-images\image-20230528110804016.png)]

  • getAuthorities:获取用户权限信息;
  • getCredentials:获取用户凭证信息,一般指密码;
  • getDetails:获取用户详细信息;
  • getPrincipal:获取用户身份信息,用户名、用户对象等;
  • isAuthentiacted:用户是否认证成功

登录后的数据保存(SecurityContextHolder)

SecurityContextHolder 用来获取登录之后的用户信息。SpringSecurity 会将登录用户数据保存在 Session 中。但是,为了使用方便,SpringSecurity 在此基础上做了一些改进,其中最主要的一个变化就是线性绑定。当用户登录成功后,SpringSecurity 会将登录成功的用户信息保存到 SecurityContextHolder 中。SecurityContextHolder 中的数据保存默认是通过 ThreadLocal 来实现的,使用 ThreadLocal 创建的变量只能被当前线程访问,不能被其他线程访问和修改,也就是用户数据和请求线程绑定在一起。

当登录请求处理完毕后,SpringSecurity 会将SecurityContextHolder 中的数据拿出来保存到session中,同时将 SecurityContextHolder 中的数据清空。以后每当有请求到来时,SpringSecurity 就会先从 Session 中取出用户登录数据,保存到 SecurityContextHolder 中,方便在该请求的后续处理过程中使用,同时在请求结束时将 SecurityContextHolder 中的数据拿出来保存到 Session 中,然后将Security 的 SecurityContextHolder 中的数据清空。这一策略非常方便用户在 Controller、Service 层以及任何代码中获取当前登录用户数据。

其实它就是为了方便我们拿用户信息数据,免得每次都得从 Session 会话中拿,从Session会话中拿,不好的地方就是要进行 SessionID 的判断,封装到SecurityContextHolder中就减少了判断这一步,直接获取即可。

授权(Authorization)

通俗点说,授权就是访问控制(你可以做什么?)

当完成认证后,接下来就是授权了。在SpringSecurity 的授权体系中,有两个关键的接口:

  • AccessDecisionManager:访问决策管理器,用来决定此次访问是否被允许。

    • public interface AccessDecisionManager {
      
      	void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
      			throws AccessDeniedException, InsufficientAuthenticationException;
      
      	boolean supports(ConfigAttribute attribute);
      
      	boolean supports(Class<?> clazz);
      
      }
      
  • AccessDecisionVoter:访问决定投票器,投票器会检查用户是否具备应有的角色,进而投出赞成、反对或者弃权票。voter(选举人)

    • public interface AccessDecisionVoter<S> {
      
      	int ACCESS_GRANTED = 1;// granted:赞同
      
      	int ACCESS_ABSTAIN = 0;// abstain:弃权
      
      	int ACCESS_DENIED = -1;// denied:反对,否认
      
      	boolean supports(ConfigAttribute attribute);
      
      	boolean supports(Class<?> clazz);
      
      	int vote(Authentication authentication, S object, Collection<ConfigAttribute> attributes);
      
      }
      

AccessDecisionVoter 和 AccessDecisionManager 都有众多的实现类,在 AccessDecisionManager 中会挨个遍历 AccessDecisionVoter,进而决定是否允许用户访问,因而 AccessDecisionVoter 和 AccessDecisionManager 两者的关系类似于 AuthenticationProvider 和 ProviderManager 之间的关系。

ConfigAttribute

在 AccessDecisionVoter 接口下的 vote 方法中,第三个参数是一个泛型参为ConfigAttribute 的Collection 集合对象。它你可以理解为是角色全称字符串的集合,内部就一个getAttribute方法。

public interface ConfigAttribute extends Serializable {
    
	String getAttribute();

}

在 Spring Security 中,用户请求一个资源(通常是一个网络接口或者一个Java方法)所需要的角色会被封装成一个 ConfigAttribute 对象,在 ConfigAttribute 中只有一个 getAttribute 方法,该方法返回一个 String 字符串,就是角色的名称,角色名称都带有一个 ROLE_ 前缀,投票器 AccessDecisionVoter 所做的事情,其实就是比较用户所具备的角色和请求某个资源所需的 ConfigAttribute 之间的关系。

二、总结

了解 Spring Security 的整体架构,主要是为了后续了解其内部原理做准备。Spring Security 作为一个安全框架,其主要就是认证和授权两大结构。

认证(Authentication)的用户信息是间接的保存在 SecurityContextHolder中,在认证管理(AuthenticationManager)中管理着多个认证执行器,由它们进行认证,认证的有关详情被封装在Authenticatoin中。

授权(Authorization)中权限名可通过ConfigAttribute通过getAttribute方法进行获取,通过AccessDecisionManager判断访问是否允许,而判断的依据是AccessDecisionVoter的投票vote方法的结果。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CISCN 2023 初赛 pwn——Shellwego 题解

这是一个用go语言写的elf程序&#xff0c;没有PIE。这也是本蒟蒻第一次解go pwn题&#xff0c;故在此记录以便参考。 而且&#xff0c;这还是一个全部符号表被抠的go elf&#xff0c;直接面对一堆不知名的函数实在有些应付不来&#xff0c;因此在比赛时委托逆向的队友把符号表…

2023/5/28总结

static static:静态&#xff0c;可以修饰成员方法&#xff0c;成员变量。&#xff08;是所有成员共享的&#xff09; static修饰的特点&#xff1a; 被类的所有对象共享&#xff08;判断是否使用静态关键字的条件&#xff09;可以通过类名和对象名调用在定义对象时&#xff0c;…

图【数据结构】

目录 一、图的定义和基本术语 二、图的类型定义 三、图的存储结构 1、数组&#xff08;邻接矩阵&#xff09;表示法 二、邻接表&#xff08;链式&#xff09;表示法 三、图的邻接表的存储表示 四、十字链表与邻接多重链表 &#xff08;1&#xff09;十字链表 &#xff…

113.删除有序数组中的重复项 removeDuplicatesFromSortedArray

文章目录 题目描述解题思路代码详解运行截图 题目描述 题目链接 给你一个 升序排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元…

Java中ReentrantLock的概念深入理解

ReentrantLock和Synchronized的区别 核心区别 ReentrantLock是一个类&#xff0c;Synchronized是Java中的一个关键字。 两者都是JVM层面实现互斥锁的方式 效率区别 线程竞争激烈推荐使用ReentrantLock去实现&#xff0c;不存在锁竞争观念&#xff1b; Synchronized是存在锁升…

大数据Doris(二十九):Broker Load导入HDFS csv 格式数据并提取文件路径中的分区字段

文章目录 Broker Load导入HDFS csv 格式数据并提取文件路径中的分区字段 一、创建Doris表 二、准备HDFS数据<

蚁群算法(解决TSP问题)

一、概述 蚂蚁在寻找食物源时&#xff0c;会在其经过的路径上释放一种信息素&#xff0c;并能够感知其它蚂蚁释放的信息素。信息素浓度的大小表征到食物源路径的远近&#xff0c;信息素浓度越高&#xff0c;表示对应的路径距离越短。通常&#xff0c;蚂蚁会以较大的概率优先…

chatgpt赋能python:Python文件复制粘贴到另一个目录

Python文件复制粘贴到另一个目录 Python是一种通用编程语言&#xff0c;可用于各种任务&#xff0c;包括文件复制和移动。在本文中&#xff0c;我们将探讨Python中的文件复制粘贴到另一个目录。 为什么要使用Python进行文件复制粘贴&#xff1f; Python提供了强大的文件处理…

case when用法

case when的基本使用&#xff1a; Case when 的用法: 一旦满足了某一个WHEN, 则这一条数据就会退出CASE WHEN , 而不再考虑 其他CASE。 Case when 的用法 -- -搜索Case函数: Case函数(Case搜索函数): 判断表达式的真假,如果为真,返回结果;如果为假,返回else值;如果未定义el…

批处理文件(.bat)启动redis及任何软件(同理)

批处理文件 每次从文件根目录用配置文件格式来启动redis太麻烦了 可以在桌面上使用批处理文件&#xff08;.bat&#xff09;启动Redis&#xff0c;请按照以下步骤进行操作&#xff1a; 打开文本编辑器&#xff0c;如记事本。 在编辑器中输入以下内容&#xff1a; 将文件保存…

70.爬楼梯问题+746.使用最小花费爬楼梯

目录 一、70.爬楼梯问题分析 二、代码 三、746.使用最小花费爬楼梯分析 四、代码 一、70.爬楼梯问题分析 70. 爬楼梯 - 力扣&#xff08;LeetCode&#xff09; 二、代码 class Solution { public:int climbStairs(int n) {if(n1||n2)return n;vector<int>dp(n1);dp…

线性表的链式表示——单链表

目录 一、单链表的定义二、单链表上基本操作的实现1、采用头插法建立单链表2、采用尾插法建立单链表3、按序号查找结点值4、按值查找表结点5、插入结点操作6、删除结点操作7、求表长操作 三、双链表、循环链表、静态链表 顺序表可以随时存取表中的任意一个元素&#xff0c;它的…

翻译:开源软件的架构(volume2): 可伸缩web框架及分布式系统

英文源地址 开源软件已经成为构建一些超大型网站的基础组成部分了.随着这些网站的成长, 围绕着它们软件架构的最佳实践与指导思想开始涌现.本文尝试去阐述设计大型网站时的需要考虑一些关键问题, 以及用于实现这些目标的基础组件. 本文主要关注web系统,尽管其中一些内容也适用于…

网络安全-01-VMware安装Kali部署DVWA

网络安全-01-VMware安装Kali&部署DVWA &#x1f53b;一、Kali简介&下载&#x1f4d7; 二、VMware安装Kali&#x1f4f0; 2.1 新建虚拟机&#x1f4f0; 2.2 开始安装Kali&#x1f4f0; 2.3 更换apt源为国内源&#x1f4f0; 2.4 启动mysql-这里使用自带的maridb&#x1f…

【Python 垃圾回收】零基础也能轻松掌握的学习路线与参考资料

Python 垃圾回收是 Python 运行机制中的重要环节。了解 Python 垃圾回收机制可帮助开发者高效编写 Python 代码&#xff0c;并避免潜在的内存泄漏问题。本文将介绍 Python 垃圾回收的学习路线&#xff0c;并给出参考资料和优秀实践。 Python 垃圾回收机制 Python 使用引用计数…

关于社会脑研究的fMRI和fNIRS超扫描方法

导读 近来&#xff0c;“社会脑”(即大脑在社会情境中是如何工作的&#xff0c;以及我们社会行为的机制是什么)在神经科学文献中获得了很多关注&#xff0c;主要是因为最近开发的技术允许研究人类社会认知的不同方面及其与大脑的关联。在这种情况下&#xff0c;超扫描技术拓宽…

如何在华为OD机试中获得满分?Java实现【质数因子】一文详解!

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Java华为OD机试真题(2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述4. Java算法源码5. 测试6.解题思路1. 题目描述 功能:输入一个正整数,…

vue小案例TodoList

1.首先我们分析怎么把一个页面拆成多个组件&#xff0c;如下图&#xff0c;我们可以拆成MyHeader、MyList、MyItem、MyFooter&#xff0c;其中MyList包含MyItem 2.观看如下代码&#xff08;我们把MyItem作为MyList的子组件&#xff0c;在父组件中使用v-for指令来循环展示子组件…

【java基础】Map集合

大家好&#x1f44b;&#xff0c;今天我来给大家科普一下Java中的map集合。map是Java中非常重要的数据结构之一&#xff0c;经常被用于存储键值对。 【有关这部分知识的思维导图放在文章末尾了&#xff0c;需要的C友请自取】 正文开始&#xff1a; 一、Map集合概述 我们知道&…

柱状图中最大的矩形

题目链接 柱状图中最大的矩形 题目描述 注意点 无 解答思路 暴力破解根据每根柱子x以x的高度作为矩形的高度找到其相邻能组成矩形的柱子&#xff0c;遍历所有柱子即可找到最大矩形&#xff0c;但是时间复杂度是O(n)&#xff0c;最终运行结果也超时了上面暴力破解的方法中…