Spring Security的认证和授权(1)

news2025/1/15 23:38:57

1、Spring Security 简介

Java企业级开发生态丰富,无论你想做哪方面的功能,都有众多的框架和工具可供选择, 以至于SUN公司在早些年不得不制定了很多规范,这些规范在今天依然影响着我们的开发, 安全领域也是如此,然而,不同于其他领域,在Java企业级开发中,安全管理方面的框架非常少,一般来说,主要有三种方案:

  • Shiro
  • Spring Security
  • Sa-Token
  • 开发者自己实现

Shiro本身是一个老牌的安全管理框架,有着众多的优点,例如轻量、简单、易于集成、 可以在JavaSE环境中使用等。不过,在微服务时代,Shiro就显得力不从心了,在微服务面前, 它无法充分展示自己的优势。

Spring Security作为Spring家族的一员,在和Spring家族的其他成员如Spring Boot、Spring Cloud等进行整合时,具有其他框架无可比拟的优势,同时对OAuth2有着良好的支持,再加 上 Spring Cloud 对 Spring Security 的不断加持(如推出 Spring Cloud Security),让 Spring Security 不知不觉中成为微服务项目的首选安全管理方案。

Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、Session会话、单点登录、OAuth2.0、微服务网关鉴权等一系列权限相关问题。

也有开发者选择自己实现安全管理,这一部分人不在少数,但是一个系统 的安全,不仅仅是登录和权限控制这么简单,我们还要考虑各种各样可能存在的网络攻击以及防御策略,从这个角度来说,开发者自己实现安全管理也并非是一件容易的事情,只有大公司才有足够的人力物力去支持这件事情。

2、Spring Security 核心功能

对于一个安全管理框架而言,无论是Shiro还是Spring Security,最核心的功能,无非就是如下两方面:

  • 认证
  • 授权

通俗点说,认证就是身份验证(你是谁?),授权就是访问控制(你可以做什么?)

2.1、认证

Spring Security支持多种不同的认证方式,这些认证方式有的是Spring Security自己提供的认证功能,有的是第三方标准组织制订的。Spring Security集成的主流认证机制主要有如下几种:

  • 表单认证
  • OAuth2.0 认证
  • SAML2.0 认证
  • CAS 认证
  • RememberMe 自动认证
  • JAAS 认证
  • OpenlD 去中心化认证
  • Pre-Authentication Scenarios 认证口
  • X509认证
  • HTTP Basic 认证
  • HTTP Digest 认证

作为一个开放的平台,Spring Security提供的认证机制不仅仅包括上面这些,我们还可以通过引入第三方依赖来支持更多的认证方式,同时,如果这些认证方式无法满足我们的需求, 我们也可以自定义认证逻辑,特别是当我们和一些“老破旧“的系统进行集成时,自定义认证逻辑就显得非常重要了。

2.2、授权

无论釆用了上面哪种认证方式,都不影响在Spring Security中使用授权功能。Spring Security支持基于URL的请求授权、支持方法访问授权、支持SpEL访问控制、支持域对象安全(ACL),同时也支持动态权限配置、支持RBAC权限模型等,总之,我们常见的权限管理需求,Spring Security基本上都是支持的。

2.3、其它

在认证和授权这两个核心功能之外,Spring Security还提供了很多安全管理的“周边功能”, 这也是一个非常重要的特色。

大部分Java工程师都不是专业的Web安全工程师,自己开发的安全管理框架可能会存在 大大小小的安全漏洞,而Spring Security的强大之处在于,即使你不了解很多网络攻击,只要使用了 Spring Security,它会帮助我们自动防御很多网络攻击,例如CSRF攻击、会话固定攻击等,同时Spring Security还提供了 HTTP防火墙来拦截大量的非法请求。由此可见,研究Spring Securityr也是研究常见的网络攻击以及防御策略。

对于大部分的Java项目而言,无论是从经济性还是安全性来考虑,使用Spring Security 无疑是最佳方案。

3、Spring Security 整体架构

3.1、认证和授权

3.1.1、认证

在 Spring Security 的架构设计中,认证(Authentication)和授权(Authorization)是分开的,无论使用什么样的认证方式,都不会影响授权,这是两个独立的存在,这种独立带来的好处之一,就是Spring Security可以非常方便地整合一些外部的认证方案。

在Spring Security中,用户的认证信息主要由Authentication的实现类来保存, Authentication 接口定义如下:

public interface Authentication extends Principal, Serializable {
	Collection<? extends GrantedAuthority> getAuthorities();
	Object getCredentials();
	Object getDetails();
	Object getPrincipal();
	boolean isAuthenticated();
	void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}

这里接口中定义的方法如下:

  • getAuthorities方法:用来获取用户的权限。
  • getCredentials方法:用来获取用户凭证,一般来说就是密码。
  • getDetails方法:用来获取用户携带的详细信息,可能是当前请求之类等。
  • getPrincipal方法:用来获取当前用户,例如是一个用户名或者一个用户对象。
  • isAuthenticated:当前用户是否认证成功。

用户使用用户名/密码登录或使用Remember-me登录时,都会对应一个不同的 Authentication 实例。Spring Security中的认证工作主要由AuthenticationManager接口来负责,下面来看一下该接口的定义:

public interface AuthenticationManager {
	Authentication authenticate(Authentication authentication) throws AuthenticationException;
}

AuthenticationManager只有一个authenticate方法可以用来做认证,该方法有三个不同的返回值:

  • 返回Authentication, 表示认证成功。
  • 抛出AuthenticationException异常,表示用户输入了无效的凭证。
  • 返回null,表示不能断定。

AuthenticationManager 最主要的实现类是 ProviderManager,ProviderManager 管理了众多的 AuthenticationProvider 实例,AuthenticationProvider 有点类似于 AuthenticationManager, 但是它多了一个supports方法用来判断是否支持给定的Authentication类型。

public interface AuthenticationProvider {
	Authentication authenticate(Authentication authentication) throws AuthenticationException;
	boolean supports(Class<?> authentication);
}

由于Authentication拥有众多不同的实现类,这些不同的实现类又由不同的 AuthenticationProvider 来处理,所以 AuthenticationProvider 会有一个 supports 方法,用来判断当前的 AuthenticationProvider 是否支持对应的 Authentication。

关键点 :
在一次完整的认证流程中,可能会同时存在多个AuthenticationProvider (例如,项目同时支持form表单登录和短信验证码登录),多个AuthenticationProvider统一由ProviderManager 来管理。同时,ProviderManager具有一个可选的parent, 如果所有的AuthenticationProvider 都认证失败,那么就会调用parent进行认证。parent相当于一个备用认证方式,即各个 AuthenticationProvider都无法处理认证问题的时候,就由parent出场收拾残局。

3.1.2、 授权

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

  • AccessDecisionManager
  • AccessDecisionVoter

AccessDecisionManager则是一个决策器,来决定此次访问是否被允许。
AccessDecisionVoter是一个投票器,投票器会检查用户是否具备应有的角色,进而投出赞成、反对或者弃权票。

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

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

3.2、Web安全

在Spring Security中,认证、授权等功能都是基于过滤器来完成的。下表列出了 Spring Security中常见的过滤器,注意这里说的是否默认加载是指引入Spring Security依赖之后,开发者不做任何配置时,会自动加载的过滤器。
在这里插入图片描述
在这里插入图片描述
开发者所见到的Spring Security提供的功能,都是通过这些过滤器来实现的,这些过滤器按照既定的优先级排列,最终形成一个过滤器链,开发者也可以自定义过滤器,并通过@Order 注解去调整自定义过滤器在过滤器链中的位置。

需要注意的是,默认过滤器并不是直接放在Web项目的原生过滤器链中,而是通过一个FilterChainProxy 来统一管理。Spring Security 中的过滤器链通过 FilterChainProxy 嵌入到 Web 项目的原生过滤器链中,如下图所示。

在这里插入图片描述
在Spring Security中,这样的过滤器链不仅仅只有一个,可能会有多个,如下图所示。 当存在多个过滤器链时,多个过滤器链之间要指定优先级,当请求到达后,会从 FilterChainProxy进行分发,先和哪个过滤器链匹配上,就用哪个过滤器链进行处理。当系统中存在多个不同的认证体系时,那么使用多个过滤器链就非常有效。

在这里插入图片描述
FilterChainProxy 作为一个顶层管理者,将统一管理 Security Fliter。 FilterChainProxy 本身将通过Spring框架提供的DelegatingFilterProxy整合到原生过滤器链中,所以还可以做进一步的优化,如下图所示。
在这里插入图片描述

3.3、登录数据保存

如果不使用Spring Security这一类的安全管理框架,大部分的开发者可能会将登录用户数据保存在Session中,事实上,Spring Security也是这么做的。但是,为了使用方便,Spring Security 在此基础上还做了一些改进,其中最主要的一个变化就是线程绑定。

当用户登录成功后,Spring Security会将登录成功的用户信息保存到SecurityContextHolder 中。SecurityContextHolder 中的数据保存默认是通过ThreadLocal来实现的,使用ThreadLocal 创建的变量只能被当前线程访问,不能被其他线程访问和修改,也就是用户数据和请求线程绑定在一起。当登录请求处理完毕后,Spring Security会将SecurityContextHolder中的数据拿出来保存到Session中,同时将SecurityContextHolder中的数据清空。以后每当有请求到来时, Spring Security就会先从Session中取出用户登录数据,保存到SecurityContextHolder 中,方便在该请求的后续处理过程中使用,同时在请求结束时将SecurityContextHolder中的数据拿岀来保存到Session中,然后将SecurityContextHolder 中的数据清空。

这一策略非常方便用户在Controller或者Service层获取当前登录用户数据,但是带来的另外一个问题就是,在子线程中想要获取用户登录数据就比较麻烦。Spring Security对此也提供了相应的解决方案,如果开发者使用@Async注解来开启异步任务的话,那么只需要添加如下配置,使用Spring Security提供的异步任务代理,就可以在异步任务中从SecurityContextHolder里边获取当前登录用户的信息:

@Configuration
public class ApplicationConfiguration extends AsyncConfigurerSupport {
    @Override
    public Executor getAsyncExecutor() {
        return new DelegatingSecurityContextExecutorService(Executors.newFixedThreadPool(5));
    }
}

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

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

相关文章

TOGAF架构开发方法—初步阶段

本章描述了满足新企业体系结构业务指令所需的准备和启动活动,包括组织特定体系结构框架的定义和原则的定义。 一、目标 初步阶段的目标是: 确定组织所需的体系结构功能: 审查进行企业架构的组织背景确定受体系结构功能影响的企业组织的元素并确定其范围确定与架构功能相交的…

php 遍历PHP数组的7种方式

在PHP中&#xff0c;遍历数组有多种方式可以选择。以下是最常用的几种方式&#xff1a; 使用foreach循环 $array array("apple", "banana", "orange"); foreach($array as $value){echo $value . "<br>"; } 输出结果&#xff…

工程监测仪器振弦传感器信号转换器在桥梁安全监测中的重要性

工程监测仪器振弦传感器信号转换器在桥梁安全监测中的重要性 桥梁是人类社会建设过程中最重要的交通基础设施之一&#xff0c;对于保障人民出行、促进经济发展具有极其重要的作用。由于桥梁结构在长期使用过程中受到环境因素和负荷的影响&#xff0c;会逐渐发生变形和损伤&…

QT学习笔记-QT程序执行Linux Shell命令实现动态添加路由

QT学习笔记-QT程序执行Linux Shell命令实现动态添加路由 背景关键代码程序界面 背景 在使用QT进行Linux下应用程序开发时&#xff0c;在特定业务需求下&#xff0c;需要在程序中执行Linux的Shell命令。QT中执行Linux命令可以通过QProcess类和system来实现&#xff0c;如果需要…

使用 Service 把前端连接到后端

使用 Service 把前端连接到后端 如何创建前端&#xff08;Frontend&#xff09;微服务和后端&#xff08;Backend&#xff09;微服务。后端微服务是一个 hello 欢迎程序。 前端通过 nginx 和一个 Kubernetes 服务暴露后端所提供的服务。 使用部署对象&#xff08;Deployment ob…

Android Gradle权威指南读书笔记

第一章 Gradle入门 生成Gradle Wrapper 命令&#xff1a;gradle wrapper --gradle-version 版本号自定义Gradle Wrapper task wrapper(type : Wrapper) { gradleVersion 2.4 archiveBase GRADLE USER HOME archivePath wrapper/dists distributionBase GRADLE USER HOME …

基于PHP的宠物爱好者交流平台管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

windows下8.0版本mysql创建用户并授权

简单记录下&#xff0c;可能有些杂乱 root用户登录mysql 创建用户 create user 要创建的用户名允许连接的ip identified by 用户名对应的密码; flush privileges; //刷新权限举个例子&#xff1a; create user test1localhost identified by test1; flush privileges; …

docker 基本用法-操作镜像

1.下载镜像 docker search centos #默认从 Docker Hub 中搜索镜像 访问 dockerhub&#xff1a;https://registry.hub.docker.com docker pull centos 拉取镜像 如果不能拉取 方法 1.需要配置配置镜像加速器 tee /etc/docker/daemon.json << EOF {"registry-mirro…

卡尔曼滤波器公式

1、卡尔曼滤波公式如下 &#xff08;1&#xff09;预测方程&#xff1a; 预测状态向量转换矩阵*上一时刻更新的状态向量 控制矩阵*当前的系统输入 /----------------------P推导 begin-----------------------------/ 预测系统状态的协方差矩阵 E[(状态向量-预测状态向量&am…

红帽认证笔记2

文章目录 1.配置系统以使用默认存储库1.调试selinux2.创建用户账户3.配置cron4. 创建写作目录5. 配置NTP6.配置autofs配置文件权限容器解法1.修改journal配置文件2.重启服务3.拷贝文件到指定目录4.修改拥有人所属组5.修改umask6.切换elovodo用户7.登录容器仓库8.拉取镜像9.运行…

《视觉 SLAM 十四讲》V2 第 9 讲 后端优化1 【扩展卡尔曼滤波器 EKF BA+非线性优化(Ceres、g2o)】

文章目录 第9讲 后端19.1.2 线性系统和 KF9.1.4 扩展卡尔曼滤波器 EKF 不足 9.2 BA 与 图优化9.2.1 投影模型和 BA 代价函数9.2.2 BA 的求解9.2.3 稀疏性 和 边缘化9.2.4 鲁棒核函数 9.3 实践&#xff1a; Ceres BA 【Code】本讲 CMakeLists.txt 9.4 实践&#xff1a;g2o 求解 …

FTP(数据共享)

1. 软件下载 到官方网站下载FileZilla的服务端和客户端程序 网站:FileZilla - The free FTP solution 自行下载即可 2. 服务器安装与配置 2.1 安装 安装的过程非常简单&#xff0c;直接下一步就可以了&#xff0c;需要说明的是&#xff0c;下图中的端口指的是FileZill…

GCC内联汇编及其在Linux内核中的使用

1. 概述 学习 GCC 内联汇编又多了一个好处。现在让我们深入内核&#xff0c;看看一些事情是如何实际工作的。 GNU C 编译器允许您将汇编语言代码嵌入到 C 程序中。 本教程解释了如何在 ARM 架构上做到这一点(译注&#xff1a;因此&#xff0c;若要测试本文档中使用的例子&…

Android MediaMetadataRetriever setDataSource failed: status = 0xFFFFFFEA

Android MediaMetadataRetriever setDataSource抛错&#xff1a; java.lang.RuntimeException: setDataSource failed: status 0xFFFFFFEA 原因是 setDataSource(String path) path指向的视频文件大小为0或者是破损视频资源。 Android AppGlideModule,DataFetcher,ModelLoad…

力扣刷题 day48:10-18

1.4的幂 给定一个整数&#xff0c;写一个函数来判断它是否是 4 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 整数 n 是 4 的幂次方需满足&#xff1a;存在整数 x 使得 n 4x 方法一&#xff1a;不断除以4 #方法一&#xff1a;不断除…

windows本地文件上传linux 或 linux输入rz命令后出现receive.**B0100000023be50

这种现象需要客户端支持&#xff0c;或者使用Xshell工具等 但是有一种简单的方法&#xff0c;使用 sftp rootip地址 // 比如 sftp root127.0.0.2 当然&#xff0c;你要记得登录远程节点的密码&#xff1a;

什么是gpt?国内怎么用?

近年来&#xff0c;人工智能技术在国内迅猛发展&#xff0c;成为推动社会进步的重要力量。在这个数字化时代&#xff0c;智能助手在生活中的应用越来越广泛。其中&#xff0c;OpenAI的ChatGPT作为一种先进的自然语言处理模型&#xff0c;为用户提供了强大的智能对话体验。但是O…

什么是网络爬虫,爬虫的机制是那些

网络爬虫&#xff08;也称为网页蜘蛛、网络机器人或网页追逐者&#xff09;是一种按照预设规则&#xff0c;自动抓取万维网信息的程序或脚本。它们广泛应用于搜索引擎、数据挖掘、竞争情报、价格监测等各种互联网应用中。 爬虫机制是爬虫程序或机器人用来访问、抓取、索引以及…

智慧人防三维数字沙盘系统

1&#xff09;系统架构设计 智慧人防三维数字沙盘系统软件是深圳易图讯科技有限公司(www.3dgis.top)基于WebGL、WEBGIS平台引擎自主研发&#xff0c;以二三维地理空间场景为电子沙盘展示平台&#xff08;支持导入3DMAX、BIM、无人机倾斜等三维模型&#xff09;&#xff0c;以二…