当前位置: 首页 > news >正文

Spring Security 原理、源码解析及进阶

文章目录

    • 参考文献
  • 1、信息安全基础
    • 1. CIA 三要素
    • 2. Authentication Vs. Authorization
    • 3. RBAC模型
  • 2、Spring Security
    • 1. Spring Security 简介
    • 2. Spring Security 架构核心
      • 2.1 FilterChain (Servlet)
      • 2.2 [DelegatingFilterProxy](https://docs.spring.io/spring-security/reference/6.0.0-M3/servlet/architecture.html#servlet-delegatingfilterproxy)(Spring)
      • 2.3 [FilterChainProxy](https://docs.spring.io/spring-security/reference/6.0.0-M3/servlet/architecture.html#servlet-filterchainproxy) (Spring Security)
      • 2.4 [SecurityFilterChain](https://docs.spring.io/spring-security/reference/6.0.0-M3/servlet/architecture.html#servlet-securityfilterchain)
    • 3. Spring Security 认证
      • 3.1 认证流程
      • 3.2 JWT理解
    • 4. Spring Security 授权
      • 4.1 授权流程
      • 4.2 授权方式
    • 5. Spring Security 实践
      • 5.1 Security 版本
      • 5.2 Security 基本使用
  • 3、Spring Oauth2 - 分布式版本的Security框架
    • 1. OAuth2 简介
      • 1.1 基础概念
      • 1.2 协议流程
      • 1.3 授权模式
      • 1.4 默认配置
      • 1.5 核心模型/组件
      • 1.6 协议端点
    • 2. Oauth2 实践
      • 2.1 Oauth2 版本
      • 2.2 Oauth2 基本应用
      • 2.3 Oauth2 测试
        • 1) spring-security-test
        • 2) spring-addons-oauth2-test

参考文献

  • Spring Security 相关:
    • https://docs.spring.io/spring-security/reference/index.html
    • https://wukong-doc.redhtc.com/security/spring/spring-security-review
    • https://juejin.cn/post/7046236598832201758
    • https://blog.csdn.net/weixin_45647685/article/details/124439641
  • Oauth2 相关:
    • https://jckling.github.io/2020/11/06/Notes/draft-ietf-oauth-v2-1-00/
    • https://spring.io/projects/spring-authorization-server#learn
    • https://docs.spring.io/spring-authorization-server/docs/current/reference/html/index.html
    • https://www.baeldung.com/spring-security-oauth-auth-server
  • 信息安全理论相关:
    • https://blog.csdn.net/qq_43874317/article/details/126511666
    • https://juejin.cn/post/7101551757024559117
    • https://www.woshipm.com/pd/5173846.html
  • 测试相关:
    • https://docs.spring.io/spring-security/reference/6.0.0-RC1/servlet/test/index.html
    • https://github.com/ch4mpy/spring-addons/tree/master/spring-addons-oauth2-test

1、信息安全基础

1. CIA 三要素

在介绍访问控制的概念之前,有必要先介绍信息安全的一个基本原理,帮助我们更好地理解访问控制解决了信息安全的什么问题。

信息安全的内容可以简化为下列三个基本点,称为 CIA 三要素:

  • Confidentiality(保密性):指保持信息 安全与私密 的需要。

例如,我们的银行卡密码在银行系统中只有我们自己能知道,如果除此以外的人知道了,那么则说明这个系统是不满足信息安全 Confidentiality 条件的,那么这个系统就是不安全的。

  • Integrity(完整性):是指保护信息不被未经授权的用户 不当更改或修改 的概念。

例如,我们的银行卡密码不能被其他任何人更改,只有我们自已或者经过我们确认授权的安全管理员才能更改密码。

  • Availability(可用性):指信息可在需要时使用的概念。

例如针对 Web 服务过载的攻击(DDoS)就是对可用性的攻击。

**访问控制 **对于保证信息的 Confidentiality 和 Integrity 至关重要。Confidentiality 条件要求只有授权用户才能读取信息,而 Integrity 条件要求只有授权用户才能以授权方式更改信息。
**访问控制 **在保持可用性方面作用不太明显,但它显然具有重要作用:例如对于一个接口,平均响应时间3s,在没有访问控制时,任意一个人都能发起大量请求让系统down掉;但如果有访问控制,那么恶意攻击者的未授权请求就直接被快速拒绝掉,避免对系统负载造成影响。

2. Authentication Vs. Authorization

用户认证(Authentication)和 授权(Authorization)是访问控制(Access Control)的基础。它们是不同的概念,但经常混淆。部分混淆源于两者之间的密切关系:正确的授权实际上取决于认证。

  • 认证

**认证 **是确定用户声明的身份是否合法的过程。

  • 授权

虽然身份认证是一个确定我是谁的过程,但授权决定了我们可以做什么。授权是指关于“是否授予用户访问系统资源的权限”的决定。信息系统必须维护用户ID和系统资源之间的某种关系,可能通过将授权用户列表附加到资源,或通过存储每个用户 ID 的可访问资源列表。

Screen Shot 2022-11-20 at 15.41.57.png

3. RBAC模型

目前主流的访问控制模型:RBAC模型——基于角色的访问控制。而 Spring Security 框架就是 RBAC 模型的一种实现。
Screen Shot 2022-11-24 at 22.15.52.png
四个基本要素:用户(U)、角色®、会话(S)和权限§
RBAC模型 是目前国际上流行的先进的安全访问控制方法。它通过
分配和取消
角色来完成用户权限的授予和取消,并且提供角色分配规则;
整个访问控制**过程分两个部分:**访问权限与角色相关联,角色再与用户关联,从而实现了用户与访问权限的逻辑分离。
**优点:**简化了用户和权限的关系,易扩展、易维护。
**缺点:**RBAC模型没有提供操作顺序的控制机制,这一缺陷使得 RBAC模型 难以适应那些对操作次序有严格要求的系统。

2、Spring Security

1. Spring Security 简介

  • https://wukong-doc.redhtc.com/security/spring/spring-security-review/
  • Spring Security 是一个功能强大且高度可定制的身份认证和访问控制框架。它实际上是保护基于 Spring 的应用程序的标准。
  • Spring Security是一个框架,侧重于为 Java应用程序 提供身份认证和授权。与所有 Spring 项目一样,Spring Security 的真正强大之处在于它可以轻松地扩展以满足定制需求。

2. Spring Security 架构核心

image.png

2.1 FilterChain (Servlet)

责任链设计模式:责任链模式是一种行为设计模式,允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

FilterChain 中的 Filters 主要有两方面作用:

  • 修改 HttpServletRequest 或 HttpServletResponse,这样 FilterChain 后续的 Filters 或 Servlet 得到的就是被修改后的请求和响应内容。
  • Filter 会拦截请求,自己作出响应,相当于断开了 FilterChain,导致后续的 Filters 和 Servlet 无法接收到该请求。

2.2 DelegatingFilterProxy(Spring)

  • Spring 提供了一个 DelegatingFilterProxy 代理类,它实现了 Filter,因此可以被注入到 FilterChain 中;同时,当请求到来时,它会把请求转发到 Spring 容器中实现了 Filter 接口的 Bean 实体,所以 DelegatingFilterProxy 桥接了 Servlet 容器和 Spring 容器。

2.3 FilterChainProxy (Spring Security)

  • 其作用是用来管理 Spring Security 中各种过滤器链(并非 Servlet 容器中的过滤器链),可以认为是 Spring Security 功能的入口。FilterChainProxy 被包裹在 DelegatingFilterProxy 中,因此调用时机也由 DelegatingFilterProxy 决定。

2.4 SecurityFilterChain

  • Security Filters 通过 SecurityFilterChain API 被关联到FilterChainProxy,往往多个SecurityFilterChain负责不同的任务。
  • Security默认过滤器实例的顺序很重要。

3. Spring Security 认证

3.1 认证流程

这里介绍 Spring Security 的登录认证功能是如何实现的。
具体流程如下:
未命名文件 (15).png

  • SecurityContextHolder - 是 Spring Security 存储身份验证人员详细信息的地方。
  • SecurityContext - 通过SecurityContextHolder获取,包含了经过身份验证的用户的Authentication。
  • Authentication - 可以通过AuthenticationManager进行身份验证后产生,或者直接从SecurityContext得到。
  • AuthenticationManager - 定义 Spring Security 的过滤器如何执行身份验证的 API 。这是一个接口,只有一个函数 authenticate。
  • ProviderManager - 最常见的 AuthenticationManager 实现,这个类可以管理多个 Provider。
  • AuthenticationProvider - 用于 ProviderManager 执行特定类型的身份验证。这是一个接口,里面有一个authenticate与supports函数,Spring 中大部分认证的内置类都继承了这个接口。
  • UserDetailsService - 是 DaoAuthenticationProvier 与特定用户信息来源进行解耦的地方,UserDetailsService 由 UserDetails 和 UserDetailsManager 所构成;UserDetails 和 UserDetailsManager各司其责,一个是对基本用户信息进行封装,一个是对基本用户信息进行管理。

3.2 JWT理解

JWT(Json Web Token),是一个非常轻巧的规范。这个规范允许我们使用JWT在两个组织之间传递安全可靠的信息。而 JWS(JSON Web Signature)并不等于JWT,它只是JWT的一种实现,除了JWS外,还有 JWE (JSON Web Encryption) 也是 JWT 的一种实现。
Screen Shot 2022-11-25 at 06.46.09.png

4. Spring Security 授权

4.1 授权流程

这里介绍 Spring Security 的授权功能是如何实现的。
image.png

  • ①首先,AuthorizationFilter 通过 SecurityContextHolder 得到 Authentication,这里通过一个Supplier来实现延迟获取。
  • ②其次,AuthorizationFilter 通过 HttpServletRequest, HttpServletResponse 与 FilterChain 创建了一个FilterInvocation。
  • ③下一步,将 Supplier 与 FilterInvocation【或者是HttpServletRequest】 传递给 AuthorizationManager
    • ④如果授权失败,后抛出AccessDeniedException,这个异常会被 ExceptionTranslationFilter 捕获并处理。
    • ⑤如果授权成功,AuthorizationFilter会继续FilterChain的正常请求流程。

4.2 授权方式

  • 基于角色的授权
http.authorizeRequests().antMatchers("/static/**").permitAll()//index页面可以由user或admin访问.antMatchers("/index").hasAnyRole("USER", "ADMIN")//除了上面以外的所有内容,只能是admin访问.anyRequest().hasRole("ADMIN");
  • 基于权限的授权
// 基于权限的授权与角色类似,需要以`hasAnyAuthority`或`hasAuthority`进行判断
http.authorizeRequests().anyRequest().hasAnyAuthority("page:index");
  • 使用注解判断权限

首先需要在相应的配置类上开启;

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {}

接着就可以直接在需要添加权限验证的请求映射上添加注解,
通过添加@PreAuthorize@PostAuthorize注解,可以在执行之前或之后判断权限,如果没有对应的权限或对应的角色,就无法访问页面。

@PreAuthorize("hasRole('USER')")   //判断是否为user角色,只有此角色才可以访问
// @PostAuthorize("hasRole('USER')")  
@RequestMapping("/index")
public String index(){return "index";
}

5. Spring Security 实践

5.1 Security 版本

Spring Security 5.7.5
Spring Security 6.0.0 [最新]

5.2 Security 基本使用

Demo: https://github.com/PengfeiMiaoTW/Spring-Security-Demo

3、Spring Oauth2 - 分布式版本的Security框架

1. OAuth2 简介

OAuth 是一个关于授权(authorization)的开放网络标准,使得第三方应用可以使用该令牌在限定时间限定范围访问指定资源。

1.1 基础概念

OAuth 定义了四种角色:

  • 资源所有者”(resource owner):能够授予对受保护资源的访问权限的实体。当资源所有者是一个人时,它被称为终端用户。有时缩写为“RO”。
  • 资源服务器”(resource server):托管受保护资源的服务器,能够接收和响应通过访问令牌对受保护资源的请求。有时缩写为“RS”。
  • 客户端”(client):代表资源所有者请求受保护资源的应用程序。术语“客户端”并不指定任何特定的实现特征(例如,应用程序是在一台服务器、台式机或其他设备上运行)。
  • 授权服务器”(authorization server):成功认证资源所有者并获得授权后,为客户端颁发访问令牌的服务器。有时缩写为“AS”。

1.2 协议流程

明确概念后,就可以看 OAuth2 的协议握手流程,摘自 RFC6749
image.png
(A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源。

1.3 授权模式

Oauth2.1 根据使用场景不同,分成了2种模式

  • 授权码模式(authorization code)
  • 客户端模式(client credentials)

授权码模式使用到了回调地址,是最为复杂的方式,通常网站中经常出现的微博,qq第三方登录,都会采用这个模式。**授权许可 **是客户端用于获得访问令牌的凭据,代表了资源所有者(对访问其受保护资源)的授权。除了这两种模式外,Oauth2.1 定义其他类型的扩展机制。

1.4 默认配置

https://docs.spring.io/spring-authorization-server/docs/current/reference/html/getting-started.html#developing-your-first-application

1.5 核心模型/组件

  • RegisteredClient** - **客户端实体
  • RegisteredClientRepository
  • OAuth2Authorization** **- 授权实体(客户端-client_credentials/用户)
  • OAuth2AuthorizationService
  • OAuth2AuthorizationConsent
  • OAuth2AuthorizationConsentService
  • OAuth2TokenContext - token上下文
  • OAuth2TokenGenerator
  • OAuth2TokenCustomizer

1.6 协议端点

Spring Authorization Server(Oauth2.1 具体实现)还提供了一种实现最小配置的默认配置形式。就是通过OAuth2AuthorizationServerConfiguration这个类。
这个类的源码路径为
org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration
OAuth2AuthorizationServerConfiguration类中注入一个叫做authorizationServerSecurityFilterChain的 bean,有了这个 bean,就会支持如下协议端点:

  • OAuth2 Authorization endpoint(授权端点)- /oauth2/authorize
  • OAuth2 Token endpoint(令牌请求端点)- /oauth2/token
  • OAuth2 Token Introspection endpoint(令牌自省端点)- /oauth2/introspect
  • OAuth2 Token Revocation endpoint(令牌撤销端点)- /oauth2/revoke
  • OAuth2 Authorization Server Metadata endpoint(授权服务器元信息端点)
  • JWK Set endpoint(JWK公钥令牌端点)- /oauth2/jwks
  • OpenID Connect 1.0 Provider Configuration endpoint
  • OpenID Connect 1.0 UserInfo endpoint

对于协议端点的理解:

OAuth2 在 Security 原有功能的基础上进行分布式的支持和拓展,抽象和封装出一系列的功能模块,对于每个模块暴露出指定接口形成一个端点。
这样做方便快速理解框架,通过控制端点是否开启来减少不必要过滤链的使用从而提高效率;
同时,对于端点我们可以通过在配置中重写实例快速实现定制化,提高灵活性。

2. Oauth2 实践

2.1 Oauth2 版本

1) Oauth2 协议版本
Oauth2 最新版本是 2.1版本,与 2.0版本 的区别主要如下:

OAuth 2.0 定义了四种授权方式

  • 密码模式(resource owner password credentials) – OAuth2.1 删除了该模式
  • 授权码模式(authorization code)
  • 简化模式(implicit)-- OAuth2.1 删除了该模式
  • 客户端模式(client credentials)

2) Oauth2 依赖引入

仓库名项目名版本号
auth-serverorg.springframework.securityspring-security-oauth2-authorization-server0.3.1 (最新已更新到0.4.0,1.0.0)
resoure-serverorg.springframework.securityspring-security-oauth2-resource-server5.6.8
jwtorg.springframework.securityspring-security-oauth2-jose5.6.8
clientorg.springframework.bootspring-boot-starter-oauth2-client2.6.13
testorg.springframework.securityspring-security-test5.6.8

2.2 Oauth2 基本应用

Screen Shot 2022-11-20 at 16.19.35.png
简易搭建流程可以分为三个步骤:

  • 配置资源服务器
  • 配置授权服务器
  • 配置 Spring Security

Demo: https://github.com/PengfeiMiaoTW/Spring-Security-Oauth2-Demo

2.3 Oauth2 测试

可以使用 spring security 提供的测试包,可以使用二次封装的工具 com.c4-soft.springaddons:spring-addons-oauth2-test。

1) spring-security-test

官方文档:https://docs.spring.io/spring-security/reference/6.0.0-RC1/servlet/test/index.html

@WithMockUser(username = "username", authorities = {"ROLE_USER", "ROLE_ADMIN"})
2) spring-addons-oauth2-test

开发文档:https://github.com/ch4mpy/spring-addons/tree/master/spring-addons-oauth2-test

@WithMockAuthentication(name = "username", authorities = {"ROLE_USER", "ROLE_ADMIN"})

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 如何使用 Qt C++ 基于 FFmpeg 开发本地视频播放器
  • Docker 系列文章导航
  • AI大模型编写多线程并发框架(六十五):发布和应用
  • C++和OpenGL实现3D游戏编程【连载7】——文字和汉字的显示
  • 使用C++编写接口调用PyTorch模型,并生成DLL供.NET使用
  • k8s ingress-nginx
  • JS设计模式之“语言之魂” - 原型模式
  • Python任务编排和工作流管理库之prefect使用详解
  • Istio基础概念
  • Spring Boot简介与体系知识导图
  • 阿里达摩院:FunASR语音识别
  • macos 使用port查询并安装python2, python3多版本, 设置默认python版本方法
  • 强化学习与自动驾驶研究内容
  • Jupyter Notebook详细教程
  • 【Python报错已解决】“ModuleNotFoundError: No module named ‘timm‘”
  • [LeetCode] Wiggle Sort
  • 【EOS】Cleos基础
  • CentOS 7 防火墙操作
  • ES6系列(二)变量的解构赋值
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • java第三方包学习之lombok
  • js中forEach回调同异步问题
  • SOFAMosn配置模型
  • SpingCloudBus整合RabbitMQ
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 聊聊redis的数据结构的应用
  • 我是如何设计 Upload 上传组件的
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • 浅谈sql中的in与not in,exists与not exists的区别
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​水经微图Web1.5.0版即将上线
  • # Kafka_深入探秘者(2):kafka 生产者
  • #Java第九次作业--输入输出流和文件操作
  • #每天一道面试题# 什么是MySQL的回表查询
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (多级缓存)多级缓存
  • (分布式缓存)Redis分片集群
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (实战篇)如何缓存数据
  • (一)springboot2.7.6集成activit5.23.0之集成引擎
  • .Net - 类的介绍
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .NET COER+CONSUL微服务项目在CENTOS环境下的部署实践
  • .NET Core 成都线下面基会拉开序幕
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .Net8 Blazor 尝鲜
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .Net下的签名与混淆
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • :=
  • [ C++ ] STL---string类的使用指南
  • [2021ICPC济南 L] Strange Series (Bell 数 多项式exp)
  • [bbk5179]第66集 第7章 - 数据库的维护 03