Spring Security 01 整体架构

news2024/12/23 6:40:06

目录

认证

 AuthenticationManager

ProviderManager

AuthenticationProvider

Authentication

SecurityContextHolder

授权

AccessDecisionManager

AccessDecisionVoter

RoleVoter

AuthenticatedVoter

Custom Voters 

ConfigAttribute


在SpringSecurity的架构中,认证跟授权是分开的,无论采用什么样的认证方式,都不会影响授权,这是两个独立的存在。

认证

官方文档:Servlet Authentication Architecture :: Spring Security

 AuthenticationManager

在 Spring Security中,认证是由该接口来负责的

AuthenticationManager is the API that defines how Spring Security’s Filters perform authentication. The Authentication that is returned is then set on the SecurityContextHolder by the controller (that is, by Spring Security’s Filters instances) that invoked the AuthenticationManager. If you are not integrating with Spring Security’s Filters instances, you can set the SecurityContextHolder directly and are not required to use an AuthenticationManager.While the implementation of AuthenticationManager could be anything, the most common implementation is ProviderManager.

public interface AuthenticationManager {
​
    /**
     * 返回 Authentication 表示认证成功
     * 抛出 AuthenticationException 表示认证失败
     */
   Authentication authenticate(Authentication authentication) throws AuthenticationException;
​
}

ProviderManager

ProviderManager is the most commonly used implementation of AuthenticationManager. ProviderManager delegates to a List of AuthenticationProvider instances. Each AuthenticationProvider has an opportunity to indicate that authentication should be successful, fail, or indicate it cannot make a decision and allow a downstream AuthenticationProvider to decide. If none of the configured AuthenticationProvider instances can authenticate, authentication fails with a ProviderNotFoundException, which is a special AuthenticationException that indicates that the ProviderManager was not configured to support the type of Authentication that was passed into it.

 

 In practice each AuthenticationProvider knows how to perform a specific type of authentication. For example, one AuthenticationProvider might be able to validate a username/password, while another might be able to authenticate a SAML assertion. This lets each AuthenticationProvider do a very specific type of authentication while supporting multiple types of authentication and expose only a single AuthenticationManager bean.

ProviderManageralso allows configuring an optional parentAuthenticationManager, which is consulted in the event that noAuthenticationProvidercan perform authentication. The parent can be any type ofAuthenticationManager, but it is often an instance ofProviderManager

 In fact, multiple ProviderManager instances might share the same parent AuthenticationManager. This is somewhat common in scenarios where there are multiple

SecurityFilterChain instances that have some authentication in common (the shared parent AuthenticationManager), but also different authentication mechanisms (the different ProviderManager instances).

 

AuthenticationProvider

You can inject multiple

AuthenticationProviders instances into

ProviderManager. Each AuthenticationProvider performs a specific type of authentication. For example,

DaoAuthenticationProvider supports username/password-based authentication, while JwtAuthenticationProvider supports authenticating a JWT token.

AuthenticationManager 主要实现类为 ProviderManager,在 ProviderManager中管理了众多 AuthenticationProvider 实例。在⼀次完整的认证流程中, Spring Security 允许存在多个 AuthenticationProvider ,⽤来实现多种认证⽅式,这些 AuthenticationProvider 都是由 ProviderManager 进⾏统⼀管理的

Authentication

The Authentication interface serves two main purposes within Spring Security:

  • An input to AuthenticationManager to provide the credentials a user has provided to authenticate. When used in this scenario, isAuthenticated() returns false.
  • Represent the currently authenticated user. You can obtain the current Authentication from the SecurityContext.

The Authentication contains:

  • principal: Identifies the user. When authenticating with a username/password this is often an instance of UserDetails.
  • credentials: Often a password. In many cases, this is cleared after the user is authenticated, to ensure that it is not leaked.
  • authorities: The GrantedAuthority instances are high-level permissions the user is granted. Two examples are roles and scopes.

 

SecurityContextHolder

The SecurityContext is obtained from the SecurityContextHolder. The SecurityContext contains an Authentication object.

The SecurityContextHolder is where Spring Security stores the details of who is authenticated. Spring Security does not care how the SecurityContextHolder is populated. If it contains a value, it is used as the currently authenticated user.

 By default, SecurityContextHolder uses a ThreadLocal to store these details, which means that the SecurityContext is always available to methods in the same thread, even if the SecurityContext is not explicitly passed around as an argument to those methods. Using a ThreadLocal in this way is quite safe if you take care to clear the thread after the present principal’s request is processed. Spring Security’s

FilterChainProxy ensures that the SecurityContext is always cleared.

SecurityContextHolder ⽤来获取登录之后⽤户信息。 Spring Security 会将登录⽤户数据保存在 Session 中。但是,为了使⽤⽅便,Spring Security在此基础上还做了⼀些改进,其中最主要的⼀个变化就是线程绑定。当⽤户登录成功后,Spring Security 会将登录成功的⽤户信息保存到 SecurityContextHolder 中。

SecurityContextHolder 中的数据保存默认是通过ThreadLocal 来实现的,使⽤ThreadLocal 创建的变量只能被当前线程访问,不能被其他线程访问和修改,也就是⽤户数据和请求线程绑定在⼀起。当登录请求处理完毕后, Spring Security 会将SecurityContextHolder 中的数据拿出来保存到 Session 中,同时将SecurityContexHolder 中的数据清空。以后每当有请求到来时, Spring Security就会先从 Session 中取出⽤户登录数据,保存到 SecurityContextHolder 中,⽅便在该请求的后续处理过程中使⽤,同时在请求结束时将SecurityContextHolder 中的数 据拿出来保存到 Session 中,然后将 Security SecurityContextHolder 中的数据清空。这⼀策略⾮常⽅便⽤户在 Controller、 Service 层以及任何代码中获取当前登录⽤户数据。

授权

官方文档:Authorization Architecture :: Spring Security

 

AccessDecisionManager

AccessDecisionManager (访问决策管理器),⽤来决定此次访问是否被允许

The AccessDecisionManager is called by the AbstractSecurityInterceptor and is responsible for making final access control decisions.

 The decide method of the AccessDecisionManager is passed all the relevant information it needs to make an authorization decision. In particular, passing the secure Object lets those arguments contained in the actual secure object invocation be inspected. For example, assume the secure object is a MethodInvocation. You can query the MethodInvocation for any Customer argument and then implement some sort of security logic in the AccessDecisionManager to ensure the principal is permitted to operate on that customer. Implementations are expected to throw an AccessDeniedException if access is denied.

The supports(ConfigAttribute) method is called by the AbstractSecurityInterceptor at startup time to determine if the AccessDecisionManager can process the passed ConfigAttribute. The supports(Class) method is called by a security interceptor implementation to ensure the configured AccessDecisionManager supports the type of secure object that the security interceptor presents

 

AccessDecisionVoter

AccessDecisionVoter (访问决定投票器),投票器会检查⽤户是否具备应有的⻆⾊,进⽽投出赞成、反对或者弃权票

 While users can implement their own AccessDecisionManager to control all aspects of authorization, Spring Security includes several AccessDecisionManager implementations that are based on voting. Voting Decision Manager describes the relevant classes.

By using this approach, a series of AccessDecisionVoter implementations are polled on an authorization decision. The AccessDecisionManager then decides whether or not to throw an AccessDeniedException based on its assessment of the votes.

         Concrete implementations return an int, with possible values being reflected in the AccessDecisionVoter static fields named ACCESS_ABSTAIN, ACCESS_DENIED and ACCESS_GRANTED. A voting implementation returns ACCESS_ABSTAIN if it has no opinion on an authorization decision. If it does have an opinion, it must return either ACCESS_DENIED or ACCESS_GRANTED.

        There are three concrete AccessDecisionManager implementations provided with Spring Security to tally the votes. The ConsensusBased implementation grants or denies access based on the consensus of non-abstain votes. Properties are provided to control behavior in the event of an equality of votes or if all votes are abstain. The AffirmativeBased implementation grants access if one or more ACCESS_GRANTED votes were received (in other words, a deny vote will be ignored, provided there was at least one grant vote). Like the ConsensusBased implementation, there is a parameter that controls the behavior if all voters abstain. The UnanimousBased provider expects unanimous ACCESS_GRANTED votes in order to grant access, ignoring abstains. It denies access if there is any ACCESS_DENIED vote. Like the other implementations, there is a parameter that controls the behavior if all voters abstain.

        You can implement a custom AccessDecisionManager that tallies votes differently. For example, votes from a particular AccessDecisionVoter might receive additional weighting, while a deny vote from a particular voter may have a veto effect.

 AccesDecisionVoter 和 AccessDecisionManager 都有众多的实现类,在AccessDecisionManager 中会换个遍历 AccessDecisionVoter,进⽽决定是否允许⽤户访问,因⽽ AaccesDecisionVoter 和 AccessDecisionManager 两者的关系类似于 AuthenticationProvider 和 ProviderManager 的关系。

RoleVoter

The most commonly used AccessDecisionVoter provided with Spring Security is the RoleVoter, which treats configuration attributes as role names and votes to grant access if the user has been assigned that role.

It votes if any ConfigAttribute begins with the ROLE_ prefix. It votes to grant access if there is a GrantedAuthority that returns a String representation (from the getAuthority() method) exactly equal to one or more ConfigAttributes that start with the ROLE_ prefix. If there is no exact match of any ConfigAttribute starting with ROLE_, RoleVoter votes to deny access. If no ConfigAttribute begins with ROLE_, the voter abstains.

AuthenticatedVoter

 Another voter which we have implicitly seen is the AuthenticatedVoter, which can be used to differentiate between anonymous, fully-authenticated, and remember-me authenticated users. Many sites allow certain limited access under remember-me authentication but require a user to confirm their identity by logging in for full access.When we have used the IS_AUTHENTICATED_ANONYMOUSLY attribute to grant anonymous access, this attribute was being processed by the AuthenticatedVoter. For more information, see AuthenticatedVoter.

Custom Voters 

You can also implement a custom AccessDecisionVoter and put just about any access-control logic you want in it. It might be specific to your application (business-logic related) or it might implement some security administration logic. For example, on the Spring web site, you can find a blog article that describes how to use a voter to deny access in real-time to users whose accounts have been suspended.

        Like many other parts of Spring Security, AfterInvocationManager has a single concrete implementation, AfterInvocationProviderManager, which polls a list of AfterInvocationProviders. Each AfterInvocationProvider is allowed to modify the return object or throw an AccessDeniedException. Indeed multiple providers can modify the object, as the result of the previous provider is passed to the next in the list.

        Please be aware that if you’re using AfterInvocationManager, you will still need configuration attributes that allow the MethodSecurityInterceptor's AccessDecisionManager to allow an operation. If you’re using the typical Spring Security included AccessDecisionManager implementations, having no configuration attributes defined for a particular secure method invocation will cause each AccessDecisionVoter to abstain from voting. In turn, if the AccessDecisionManager property “allowIfAllAbstainDecisions” is false, an AccessDeniedException will be thrown. You may avoid this potential issue by either (i) setting “allowIfAllAbstainDecisions” to true (although this is generally not recommended) or (ii) simply ensure that there is at least one configuration attribute that an AccessDecisionVoter will vote to grant access for. This latter (recommended) approach is usually achieved through a ROLE_USER or ROLE_AUTHENTICATED configuration attribute.

 

ConfigAttribute

ConfigAttribute,⽤来保存授权时的⻆⾊信息

 在 Spring Security 中,⽤户请求⼀个资源(通常是⼀个接⼝或者⼀个 Java ⽅法)需要的⻆⾊会被封装成⼀个 ConfigAttribute 对象,在 ConfigAttribute 中只有⼀个getAttribute⽅法,该⽅法返回⼀个 String 字符串,就是⻆⾊的名称。⼀般来说,⻆⾊名称都带有⼀个 ROLE_ 前缀,投票器 AccessDecisionVoter 所做的事情,其实就是⽐较⽤户所具各的⻆⾊和请求某个资源所需的 ConfigAtuibute 之间的关系。

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

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

相关文章

Linux如何使用宝塔面板搭建网站和内网穿透实现公网访问

文章目录 前言1. 环境安装2. 安装cpolar内网穿透3. 内网穿透4. 固定http地址5. 配置二级子域名6. 创建一个测试页面 转载自远程内网穿透的文章:Linux使用宝塔面板搭建网站,并内网穿透实现公网访问 前言 宝塔面板作为简单好用的服务器运维管理面板&#…

Flink从入门到精通之-06Flink 中的时间和窗口

Flink从入门到精通之-06Flink 中的时间和窗口 我们已经了解了基本 API 的用法,熟悉了 DataStream 进行简单转换、聚合的一些操作。除此之外,Flink 还提供了丰富的转换算子,可以用于更加复杂的处理场景。 在流数据处理应用中,一个…

NM储存卡数据丢失怎么办?四招数据恢复宝典

NM卡像其他类型的存储设备一样,也有可能因为各种原因导致数据丢失,比如误删除、格式化、病毒感染等。因此,在使用NM卡时,仍需注意数据备份和安全性,以避免面临重要数据丢失风险。如果不幸发生了数据丢失,应…

python中unexpected indent报错的解决办法

python中unexpected indent报错的解决办法 在我们初步学习pyton的时候,由于对python语言的学习掌握不充分,则会导致所编写的代码,运行时候报错。比如,容易报错的unexpected indent问题,下面举例说明问题。 1.举例&am…

Linux虚拟机中安装jdk的两种方法:

方法一:手动安装 1. 使用FinalShell自带的上传工具将jdk的二进制发布包上传到Linux 上传位置如图(底栏可以在图中的向下箭头位置自行打开与关闭): 注:默认上传地址为图片左侧的工作地址 2. 解压安装包,…

在vue2中用vue-echarts和v-charts绘制百度地图定制散点图

一、在vue-echarts中定制百度地图 效果 准备 安装依赖 echarts vue-echarts npm i echarts vue-echarts 在main.js中引入 import ECharts from “echarts” import VueECharts from “vue-echarts” Vue.prototype.$echarts ECharts Vue.component(“v-chart”, VueECharts…

SAS学习第4章:t检验

前话:分析试验数据的差异,一般都会假设样本值之间或者样本与标准值之间无差异,根据不同方法计算得出的t值、q值、F值等等,均表示两者之间的差异程度,值越大,两者差异越大,该假设越不成立&#x…

全网最全的AI绘画提示词网站,看这一篇就够了!

要说2023年什么最火,绝对是以ChatGPT为代表的AI工具了,特别是AI绘画,而用好AI的关键,就是要学会使用关键词,也叫提示词,提示词是AI绘画的核心,本次就给大家分享几个AI绘画关键词网站&#xff0c…

大型Android项目架构:基于组件化+模块化+Kotlin+协程+Flow+Retrofit+Jetpack+MVVM架构实现WanAndroid客户端

前言:苟有恒,何必三更眠五更起;最无益,莫过一日曝十日寒。 前言 之前一直想写个 WanAndroid 项目来巩固自己对 KotlinJetpack协程 等知识的学习,但是一直没有时间。这里重新行动起来,从项目搭建到完成前前…

奇异值分解SVD

概念 奇异值分解(singular value decomposition)是线性代数中一种重要的矩阵分解。奇异值分解在某些方面与对称矩阵或厄密矩阵基于特征向量的对角化类似。然而这两种矩阵分解尽管有其相关性,但还是有明显的不同。对称矩阵特征向量分解的基础…

数据分析师 ---- SQL强化(1)

文章目录 数据分析师 ---- SQL强化(1)写在前面题目第一步:表连接以及表拼接第二步:新建列以及填充值总结 数据分析师 ---- SQL强化(1) 写在前面 最近在找工作中发现,数据分析师的笔试多数会涉及SQL,但是笔试中SQL的难度和我们在学…

车载软件架构——闲聊几句AUTOSAR BSW(一)

我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 人生是用来体验的,不是用来演绎完美的。我慢慢能接受自己身上那些灰暗的部分,原谅自己的迟钝和平庸,允许自己出错,允许自己偶尔断电,带着缺憾拼命绽放,…

Node【初识Node】

文章目录 🌟前言🌟Node.js🌟特性:🌟1. 单线程🌟2.异步IO🌟前端中的异步🌟Node中的异步 🌟3.跨平台🌟4.运行速度快 🌟 劣势:&#x1f3…

4/20~4/21两日总结

网络编程 socket通信 socket被翻译为套接字,通过socket这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据 如何实现呢 ServerSocket类能创建Socket的服务端,Socket能创建Socket的客户端 ServerSocket中…

如何运用数字孪生可视化技术实现三维可视化智慧园区

随着城市化的进程和信息化的发展,越来越多的城市拥有了智慧园区这一新的城市形态,通过“互联网”和物联网技术,实现了各种功能部门之间的信息共享与协同,提高了园区服务的质量和效率。然而,如何更好地实现园区管理和运…

LeetCode - 168. Excel表列名称

168. Excel表列名称 给你一个整数 columnNumber ,返回它在 Excel 表中相对应的列名称。例如: A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 ... 二进制与十进制之间的转换 在做这题之前,先复习一下二进制与十进…

JUC并发编程之读写锁原理

1.图解流程 读写锁用的是同一个 Sycn 同步器,因此等待队列、state等也是同一个 t1 w.lock , t2 r.lock t1 成功上锁,流程与 ReentrantLock 加锁相比没有特殊之处,不同的是写锁状态占了 state 的低 16 位,而读锁使用…

多线程并发编程-线程篇

线程基础 什么是线程? 系统中的一个程序就是一个进程,每个进程中的最基本的执行单位,执行路径就是线程,线程是轻量化的进程。 什么是纤程? 绿色线程,由用户自己进行管理的而不是系统进行管理的&#xf…

【教程类】IDEA 打包 jar 包

最近有点累,写点简单的图文教程的东西来缓解一下 一、你需要知道的基础概念 了解了基础概念之后,可以让我们学习的更快更好哦 ~~ 1. jar JAR(Java Archive)是Java中一种常用的归档文件格式,也可以被视为一种压缩文…

学生就业统计表案例

主要分为三块: 渲染业务新增业务删除业务 一、根据持久化数据渲染页面 核心步骤: 读取localstorage 本地数据 如果有数据则转换为对象放到变量里面一会使用它渲染页面如果没有则用默认空数组 []为了测试效果,咱们可以先把initData 存入本地存储看效果…