【Spring】Spring Security 核心类介绍及Spring Security 的验证机制

Spring Security 核心类介绍及Spring Security 的验证机制

  • 一、Spring Security 核心类
    • 1.1 Authentication
    • 1.2 SecurityContextHolder
    • 1.3 UserDetails
    • 1.4 UserDetailsService
    • 1.5 GrantedAuthority
    • 1.6 DaoAuthenticationProvider
    • 1.7 PasswordEncoder
  • 二、 Spring Security 的验证机制

一、Spring Security 核心类

Spring Security 核心类包括 AuthenticationSecurityContextHolderUserDetailsUserDetailsServiceGrantedAuthorityDaoAuthenticationProviderPasswordEncoder

1.1 Authentication

Authentication 用来表示用户认证信息,在用户登录认证之前,Spring Security 会将相关信息封装为一个 Authentication 具体实现类的对象,在登录认证成功之后又会生成一个信息更全面、包含用户权限等信息的 Authentication 对象,然后把它保存在 SecurityContextHolder 所持有的 SecurityContext 中,供后续的程序进行调用,如访问权限的鉴定等。

1.2 SecurityContextHolder

SecurityContextHolder 是用来保存 SecurityContext 的。 SecurityContext 中含有当前所访问系统的用户的详细信息。默认情况下, SecurityContextHolder 将使用 ThreadLocal 来保存 SecurityContext,这也就意味着在处于同一线程的方法中,可以从 ThreadLocal 获取到当前的 SecurityContext。

Spring Security 使用一个 Authentication 对象来描述当前用户的相关信息。SecurityContextHolder 中持有的是当前用户的 SecurityContext,而 SecurityContext 持有的是代表当前用户相关信息的 Authentication 的引用。这个 Authentication 对象不需要我们自己创建,在与系统交互的过程中, Spring Security 会自动创建相应的 Authentication 对象,然后赋值给当前的 SecurityContext。开发过程中常常需要在程序中获取当前用户的相关信息,比如最常见的是获取当前登录用户的用户名。

示例代码如下:

String username = SecurityContextHolder.getContext().getAuthentication().getName();

1.3 UserDetails

UserDetails 是 Spring Security 的一个核心接口。其中定义了一些可以获取用户名、密码、权限等与认证相关的信息的方法。Spring Security 内部使用的 UserDetails 实现类大都是内置的 User 类,要使用 UserDetails,也可以直接使用该类。在 Spring Security 内部,很多需要使用用户信息的时候,基本上都是使用 UserDetails,比如在登录认证的时候。

通常需要在应用中获取当前用户的其他信息,如E-mail、电话等。这时存放在 Authentication 中的 principal 只包含认证相关信息的 UserDetails 对象可能就不能满足我们的要求了。这时可以实现的 UserDetails,在该实现类中可以定义一些获取用户其他信息的方法,这样将来就可以直接从当前 SecurityContext 的 Authentication 的 principal 中获取这些信息。

UserDetails 是通过 UserDetailsService 的 loadUserByUsername() 方法进行加载的。 UserDetailsService 也是一个接口,我们也需要实现自己的 UserDetailsService 来加载自定义的 UserDetails 信息。

1.4 UserDetailsService

Authentication.getPrincipal() 的返回类型是 Object,但很多情况下返回的其实是一个 UserDetails 的实例。登录认证的时候 Spring Security 会通过 UserDetailsService 的 loadUserByUsername() 方法获取对应的 UserDetails 进行认证,认证通过后会将该 UserDetails 赋给认证通过的 Authentication 的 principal,然后再把该 Authentication 存入 SecurityContext。之后如果需要使用用户信息,可以通过 SecurityContextHolder 获取存放在 SecurityContext 中的 Authentication 的 principal。

1.5 GrantedAuthority

Authentication 的 getAuthorities() 可以返回当前 Authentication 对象拥有的权限,即当前用户拥有的权限。其返回值是一个 GrantedAuthority 类型的数组,每一个 GrantedAuthority 对象代表赋予给当前用户的一种权限。GrantedAuthority 是一个接口,其通常是通过 UserDetailsService 进行加载,然后赋予 UserDetails 的。

GrantedAuthority 中只定义了一个 getAuthority()方法,该方法返回一个字符串,表示对应的权限,如果对应的权限不能用字符串表示,则应当返回 null。

1.6 DaoAuthenticationProvider

Spring Security 默认会使用 DaoAuthenticationProvider 实现 AuthenticationProvider 接口,专门进行用户认证的处理。 DaoAuthenticationProvider 在进行认证的时候需要一个 UserDetailsService 来获取用户的信息 UserDetails,其中包括用户名、密码和所拥有的权限等。如果需要改变认证的方式,开发者可以实现自己的 AuthenticationProvider。

1.7 PasswordEncoder

在 Spring Security 中,对密码的加密都是由 PasswordEncoder 来完成的。在 Spring Security 中,已经对 PasswordEncoder 有了很多实现,包括 md5 加密、SHA-256 加密等,开发者只要直接拿来用就可以。在 DaoAuthenticationProvider 中,有一个就是 PasswordEncoder 属性,密码加密功能主要靠它来完成。
在 Spring 的官方文档中明确指出,如果开发一个新的项目,BCryptPasswordEncoder 是较好的选择。BCryptPasswordEncoder 使用 BCrypt 的强散列哈希加密实现,并可以由客户端指定加密的强度,强度越高安全性自然就越高。

二、 Spring Security 的验证机制

Spring Security 大体上是由一堆 Filter 实现的,Filter 会在 SpringMVC 前拦截请求。 Filter 包括登出 Filter(LogoutFilter)、用户名密码验证 Filter(UsernamePasswordAuthenticationFilter)之类。Filter 再交由其他组件完成细分的功能,最常见的 UsernamePasswordAuthenticationFilter 会持有一个 AuthenticationManager 引用,AuthenticationManager 是一个验证管理器,专门负责验证。但是 AuthenticationManager 本身并不做具体的验证工作,AuthenticationManager 持有一个 AuthenticationProvider 集合,AuthenticationProvider 才是做验证工作的组件,验证成功或失败之后调用对应的 Handler。


本文完结!

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

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

相关文章

国产压缩包工具——JlmPackCore SDK说明(二)——JlmPack_Create函数说明

一、JlmPack_Create函数说明 JlmPack_Create函数是创建jlm压缩文件的核心函数,最大允许CATALOG_MAX_LIMIT(请参考Config.h)个目录,意思是包括文件夹和文件在内,遍历整个列表最大允许CATALOG_MAX_LIMIT个目录对象&#…

《昇思25天学习打卡营第4天|数据集 Dataset》

文章目录 前言:今日所学:1. 数据集加载2. 数据集迭代3. 数据集常用操作与自定义数据集 前言: 今天学习的是数据集的内容。首先,数据是深度学习的基石,高质量的数据输入能够在整个深度神经网络中发挥积极作用。MindSpo…

【UE5.1】Chaos物理系统基础——01 创建可被破坏的物体

目录 步骤 一、通过笔刷创建静态网格体 二、破裂静态网格体 三、“统一” 多层级破裂 四、“簇” 群集化的破裂 五、几何体集的材质 六、防止几何体集自动破碎 步骤 一、通过笔刷创建静态网格体 1. 可以在Quixel Bridge中下载两个纹理,用于表示石块的内外纹…

C++中的类型转换操作符:static_cast reinterpret_cast const_cast dynamic_cast

目录​​​​​​​ C语言中的类型转换 C中的类型转换 C中的类型转换操作符 static_cast reinterpret_cast const_cast volatile关键字 赋值兼容 dynamic_cast C语言中的类型转换 基本概念:赋值运算符左右两侧类型不同,或形参与实参类型不匹配…

51单片机通过控制寄存器控制设备,那么程序中变量的运算职责由谁完成的呢

在51单片机(或更广泛地说,在任何微控制器或微处理器系统中)的程序执行过程中,变量的运算职责主要由中央处理器(CPU)完成。CPU 负责执行程序中的指令,包括对各种变量进行算术和逻辑运算。 当你编…

【Android build异常】androidx导致

现象: 增加 implementation androidx.activity:activity:1.8.0后,导致build失败: 提示SDK Java_Home 1.8 而当前需要11。修改settings-Gradle为11仍不起作用。解决: 删除该行引用。 拓展: 1、compileSdkVersion …

如何在宝塔面板中配置SSL证书?

目录 一、申请证书二、登录宝塔面板配置SSL证书一、申请证书 登录华为云,进入“云证书管理服务 CCM”: 点击“购买证书”: 选择“DV(Basic)”->“DigiCert”,点击【立即购买】购买有效期为3个月的免费证书。 申请证书:

JAVA里的object类

public static String toString(Object o) // 获取对象的字符串表现形式 public static boolean equals(Object a, Object b) // 比较两个对象是否相等 public static boolean isNull(Object obj) // 判断对象是否为null pu…

linux使用Shell脚本实现内存监控告警

1.实现步骤: 1.获取当前内存情况 2.配置邮件告警,邮件信息是内存剩余状况 3.开发脚本判断内存是否小于150M,if判断 4.crontab加入脚本写规则 2.脚本文件: 在/tmp/下脚本名为Free_warn.sh #!/bin/bash Free_mem free -m | awk NR2 {pr…

基于单片机的 LED 照明灯智能调光系统设计

摘  要: 社会经济的不断发展,推动了智能化生活的进程,智能调光技术开始广泛应用在生活中,人们也逐渐提高了灯光亮灯率等的要求。基于此,笔者主要设计了基于单片机的 LED 照明灯智能调光系统,希望能够为相关…

骨传导耳机哪个牌子好?精选靠谱好用的TOP5骨传导耳机推荐!

在超过八成的音乐爱好者都面临听力健康问题的当下,骨传导耳机因其独特的听觉体验和对听力的保护,在音频设备市场中备受瞩目。但近期我发现不少用户在选购骨传导耳机时常常受到不专业产品的误导。身为有着5年经验的数码博主,在此提醒大家&…

老师怎样用微信发布期末成绩

老师们,期末季又到了,还在为如何发布成绩而头疼?今天,就让我来分享一些小技巧,让你们在微信上发布成绩更加高效,同时又能保护学生的隐私。 首先,我们要确保成绩的安全性和隐私性。在微信上&…

数据恢复篇:如何在 Android 手机上恢复未保存/删除的 Word 文档

在 Android 手机上访问 Word 文档通常很简单,但是当这些重要文件被删除或未保存时会发生什么?这种情况虽然令人痛苦,但并非毫无希望。到 2024 年,有几种强大的方法来处理此类数据丢失。本指南重点介绍如何在Android手机上恢复已删…

Python | Leetcode Python题解之第208题实现Trie(前缀树)

题目: 题解: class Trie:def __init__(self):self.children [None] * 26self.isEnd Falsedef searchPrefix(self, prefix: str) -> "Trie":node selffor ch in prefix:ch ord(ch) - ord("a")if not node.children[ch]:retur…

2008-2022年款哈弗维修手册和电路图线路图接线图资料更新

经过整理,2005-2022年款长城哈弗全系列已经更新至汽修帮手资料库内,覆盖市面上99%车型,包括维修手册、电路图、新车特征、车身钣金维修数据、全车拆装、扭力、发动机大修、发动机正时、保养、电路图、针脚定义、模块传感器、保险丝盒图解对照…

闲鱼商品详情数据接口(goodfish.item_get)

闲鱼(一个由阿里巴巴集团运营的二手交易平台)并没有公开一个名为 goodfish.item_get 的官方API接口。闲鱼(Xianyu)的API通常是私有的,主要面向其官方合作伙伴或经过特殊授权的开发者。 如果你想要获取闲鱼上的商品详情…

word怎么转换成pdf?分享3种PDF文件转换技巧

word怎么转换成pdf?在日常办公中,将Word转换成PDF可以带来诸多便利。首先,PDF格式具有跨平台的通用性,无论在哪个操作系统或设备上,都能保持文档的原始布局和格式。其次,PDF文件不容易被篡改,可…

zookeeper服务介绍

zookeeper 基础概念安装使用 基础概念 ZooKeeper是一个分布式协调服务,主要用于管理和协调大型分布式系统。它提供了一些基本功能,例如配置维护、名字服务、分布式同步和组服务,这些功能对于分布式应用程序的正常运行至关重要。 主要功能 配…

PHP中单引号双引号

在 PHP 中,字符串可以用单引号()或双引号(")括起来,但它们对变量和特殊字符的处理方式是不同的。 双引号(" ") 双引号内的变量会被解析并替换为其值。 某些特殊字符…