Spring Security OAuth2 组件

我们来系统地讲解一下 Spring Security OAuth2 这个强大的组件。我会从概念、作用、核心组件,以及实际应用场景来为你剖析。

1. 什么是 Spring Security OAuth2?

简单来说,Spring Security OAuth2 是 Spring Security 框架的一个模块,专门用来帮助你在 Spring 应用中轻松实现 OAuth 2.0 和 OpenID Connect 1.0 (OIDC) 协议。

它的核心目标不是传统的用户名密码认证,而是授权委托 (Delegated Authorization)


2. 为什么要用 OAuth2?(一个经典比喻)

想象一下这个场景:

你入住了一家酒店,你想让酒店的保洁服务帮你打扫房间,但你又不想把你的钱包和身份证(最高权限)直接给保洁员。

你会怎么做?

你会去前台,验证你的身份后,前台会给你一张房卡。这张房卡有以下特点:

  • 权限有限:只能打开你的房间门,不能打开其他房间,也不能去酒店金库。

  • 有有效期:通常只在你入住期间有效。

  • 可以吊销:如果你丢失了房卡,可以去前台挂失,让旧卡失效。

在这个比喻中:

  • 你 (Resource Owner):资源的所有者(你的房间)。

  • 保洁服务 (Client):想要访问你资源的第三方应用。

  • 酒店前台 (Authorization Server):负责认证你的身份,并给你授权(发房卡)的认证中心。

  • 你的房间 (Resource Server):存放着受保护的资源(需要用房卡才能进入)。

  • 房卡 (Access Token):一个带有时效和特定权限的“令牌”。

OAuth2 就是这个“发房卡”的标准化流程。它允许用户(你)授权一个第三方应用(保洁服务)去访问他们存储在另一个服务(你的房间)上的私有资源,而无需将用户的凭证(用户名和密码)直接暴露给第三方应用。


3. Spring Security OAuth2 的核心组件(现代架构)

在现代 Spring Boot 应用中(Spring Boot 2.x 及以上),Spring Security OAuth2 的功能被清晰地拆分成了几个独立的组件。这一点非常重要,因为网上很多旧的教程已经过时。

历史演进(重要!)
  • 旧版 (spring-security-oauth2-autoconfigure):曾提供 @EnableAuthorizationServer、@EnableResourceServer 等注解,将授权服务器、资源服务器等功能耦合在一起。这个库现在已经废弃,不推荐在新项目中使用。

  • 新版(推荐):功能被拆分,更加清晰和专注。

    • 授权服务器 (Authorization Server):独立为一个新项目 Spring Authorization Server。当你需要自己构建一个认证中心(比如自家的“统一登录平台”)时使用。

    • 客户端 (Client):由 spring-boot-starter-oauth2-client 提供。

    • 资源服务器 (Resource Server):由 spring-boot-starter-oauth2-resource-server 提供。

在绝大多数业务场景中,我们主要使用 客户端 和 资源服务器 这两个角色。


4. 两大核心应用场景及实现

场景一:作为客户端 (OAuth2 Client)

目的:让你的应用去访问一个受 OAuth2保护的资源,或者实现“通过第三方登录”的功能。

例子

  1. 你的网站需要一个“使用 GitHub/Google 账号登录”的功能。

  2. 你的后端服务需要调用 GitHub API 来获取用户的仓库列表。

如何实现?

  1. 添加依赖

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>

    content_copydownload

    Use code with caution.Xml
  2. 配置 application.yml
    在这里配置第三方认证服务商(如 GitHub)提供给你的信息。

    spring:security:oauth2:client:registration:github: # "github" 是一个自定义的注册IDclient-id: your-github-client-idclient-secret: your-github-client-secretscope: read:user # 想要获取的权限

    content_copydownload

    Use code with caution.Yaml

    Spring Boot 已经为常见的服务商(Google, GitHub, Facebook, Okta)预设了很多配置,你只需要提供 client-id 和 client-secret 即可。

  3. 配置安全规则 SecurityFilterChain

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated() // 所有请求都需要认证).oauth2Login(Customizer.withDefaults()); // 启用 OAuth2 登录流程return http.build();}
    }

    content_copydownload

    Use code with caution.Java

    仅仅添加 .oauth2Login(),Spring Security 就会自动为你完成以下所有事情:

    • 创建一个默认的登录入口 /oauth2/authorization/github。

    • 当用户访问受保护的页面时,自动重定向到 GitHub 的授权页面。

    • 用户在 GitHub 授权后,处理回调请求(redirect-uri)。

    • 用授权码(Authorization Code)换取访问令牌(Access Token)。

    • 使用 Access Token 去获取用户信息。

    • 将用户信息包装成一个 Authentication 对象,放入 SecurityContextHolder,完成登录。

场景二:作为资源服务器 (Resource Server)

目的:保护你的 API,只允许持有有效令牌(Access Token)的客户端访问。

例子

  • 你有一个前后端分离的项目,前端(如 Vue/React)在登录后获取一个 Token。

  • 前端每次请求后端的 API 时,都必须在请求头中携带这个 Token。

  • 你的后端(Spring Boot 应用)需要验证这个 Token 的有效性。

如何实现?

  1. 添加依赖

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
    </dependency>

    content_copydownload

    Use code with caution.Xml
  2. 配置 application.yml
    你需要告诉资源服务器如何验证 Token。最常见的方式是使用 JWT (JSON Web Token)。你需要提供授权服务器的公钥地址(jwk-set-uri),以便验证 JWT 的签名。

    spring:security:oauth2:resourceserver:jwt:# 你的授权服务器(如 Keycloak, Auth0, 或自建的 Spring Authorization Server)的 JWK Set URIjwk-set-uri: https://your-auth-server.com/.well-known/jwks.json

    content_copydownload

    Use code with caution.Yaml
  3. 配置安全规则 SecurityFilterChain

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize -> authorize.requestMatchers("/api/public").permitAll() // 公开API.anyRequest().authenticated() // 其他API需要认证)// 启用 OAuth2 资源服务器功能,并指定使用 JWT 进行验证.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())); return http.build();}
    }

    content_copydownload

    Use code with caution.Java

    添加 .oauth2ResourceServer() 后,Spring Security 会:

    • 自动配置一个过滤器,检查所有进来的请求的 Authorization 请求头。

    • 期望的格式是 Authorization: Bearer <your-jwt-token>。

    • 如果找到 Token,它会使用配置的 jwk-set-uri 来获取公钥,并验证 Token 的签名、有效期(exp)、颁发者(iss)等信息。

    • 如果验证通过,它会从 Token 中解析出用户权限(scope 或 scp),并创建一个 Authentication 对象,授权访问。

    • 如果 Token 无效或不存在,则拒绝访问(返回 401 Unauthorized)。


5. 整体流程示例(前后端分离应用)

一个典型的现代 Web 应用流程如下:

  1. 用户前端应用(Client)上点击“登录”。

  2. 前端应用将用户重定向到授权服务器(如 Auth0, Keycloak, 或自建的 Spring Authorization Server)。

  3. 用户在授权服务器上输入用户名和密码。

  4. 授权服务器验证成功后,将用户重定向回前端应用,并附带一个 Access Token (通常是 JWT)。

  5. 前端应用存储这个 Token(例如,在 localStorage 中)。

  6. 当用户要访问后端受保护的 API 时,前端应用在 HTTP 请求的 Authorization 头中携带这个 Token:Authorization: Bearer <token>。

  7. Spring Boot 后端(Resource Server)接收到请求。

  8. Spring Security 的 oauth2ResourceServer 过滤器拦截请求,提取 Token。

  9. 它根据 jwk-set-uri 配置,从授权服务器获取公钥,验证 Token 的签名和声明。

  10. 验证成功:请求被放行到对应的 Controller 方法,业务逻辑继续执行。

  11. 验证失败:请求被拦截,返回 401 错误。

总结

  • Spring Security OAuth2 是实现 OAuth 2.0 协议栈的官方 Spring 模块,用于构建安全的、基于令牌的授权系统。

  • 它解决了授权委托问题,避免了密码的直接共享。

  • 现代架构下,其功能主要分为客户端 (Client) 和资源服务器 (Resource Server),而授权服务器 (Authorization Server) 是一个独立的项目。

  • 作为 Client (spring-boot-starter-oauth2-client):用于实现“第三方登录”或调用外部受保护的 API。核心配置是 .oauth2Login()。

  • 作为 Resource Server (spring-boot-starter-oauth2-resource-server):用于保护你自己的 API,验证外部传入的 Token。核心配置是 .oauth2ResourceServer()。

  • 对于新项目,请务必使用新的、模块化的依赖,而不是已经废弃的旧版。

希望这个讲解能帮助你清晰地理解 Spring Security OAuth2!

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

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

相关文章

Redis的持久化功能

Redis的持久化功能能够将内存中的数据保存到磁盘&#xff0c;从而在重启后恢复数据。下面为你详细介绍Redis的两种主要持久化方式及其配置方法。 RDB&#xff08;Redis Database&#xff09;持久化 RDB持久化是通过生成某个时间点的数据集快照来实现的。它具有高性能的特点&a…

Chrome 将成为下一个 IE6

最近在技术圈刷到一个帖子&#xff0c;说&#xff1a;“Chrome 就快变成新的 IE6 了。” 乍一看有点危言耸听&#xff0c;但你一细品&#xff0c;发现还真挺像回事。 想当年&#xff1a;IE6 是怎么垮的&#xff1f; IE6 当年多风光&#xff1f;全球市场份额一度超过 90%&#…

Redis 配置文件详解redis.conf 从入门到实战

一、redis.conf 是什么&#xff1f; Redis 的配置文件&#xff08;默认命名为 redis.conf&#xff0c;Redis 8.0 之后改为 redis-full.conf&#xff09;控制着服务运行的各项参数。该文件采用以下结构&#xff1a; 指令名 参数1 参数2 ... 参数N例如&#xff1a; replicaof …

autoware docker的安装

前言 官方的安装说明&#xff1a; 官方的安装说明 安装前&#xff0c;请确认安装的硬件&#xff1a; CPU with 8 cores16GB RAM[Optional] NVIDIA GPU (4GB RAM) 满足需求 1. 安装软件依赖 这一步主要是安装三个软件&#xff1a; DockerNVIDIA Container Toolkit (pref…

AWS 解决方案深度剖析:Amazon QLDB — 构建可信赖、不可变的数据审计基石

导言&#xff1a;数据可信的挑战 在现代应用开发中&#xff0c;尤其是在金融、供应链、身份认证、政府事务、医疗记录管理等领域&#xff0c;数据完整性和历史追溯性至关重要。我们常常面临以下挑战&#xff1a; 审计困难&#xff1a; 如何证明数据从诞生至今未被篡改&#xf…

Leetcode-​1358. 包含所有三种字符的子字符串数目​

Problem: 1358. 包含所有三种字符的子字符串数目 思路 滑动窗口 解题过程 滑动窗口&#xff1a;使用左右指针 l 和 r 维护一个窗口&#xff0c;窗口内字符的频次由 cnt 记录。 右指针扩展&#xff1a;右指针 r 不断右移&#xff0c;将字符加入窗口并更新频率。 左指针收缩&a…

iTunes 无法备份 iPhone:10 种解决方法

Apple 设备是移动设备市场上最先进的产品之一&#xff0c;但有些人遇到过 iTunes 因出现错误而无法备份 iPhone 的情况。iTunes 拒绝备份 iPhone 时&#xff0c;可能会令人非常沮丧。不过&#xff0c;幸运的是&#xff0c;我们有 10 种有效的方法可以解决这个问题。您可以按照以…

Unity 接入抖音小游戏一

目录 一、搭建小游戏环境 二、接入抖音SDK 1.初始化 2.登录 3.分享 4.添加到桌面 5.侧边栏功能 6. 接入流量主 三、完整代码 下一篇传送门 Unity 接入抖音小游戏二 -CSDN博客 一、搭建小游戏环境 我这边因为没有下载其他版本的Unity所以就先用2022.3.57f1了 大家还是下载…

Node.js 项目启动命令全面指南:从入门到精通(术语版)

文章目录 Node.js 项目启动命令全面指南&#xff1a;从入门到精通一、核心启动命令深度解析1. 基础命令结构与执行机制2. 参数传递机制详解 二、常用命令分类详解1. 运行环境命令对比2. 质量保障命令详解3. 构建部署全流程 三、高级配置实战技巧1. 环境变量管理进阶2. 命令组合…

创意风格行业PPT模版分享

极简主题PPT模版&#xff0c;设计类PPT模版&#xff0c;快乐童年成长PPT模版&#xff0c;教育机构通用PPT模版&#xff0c;创意风格行业PPT模版 创意风格行业PPT模版分享&#xff1a;https://pan.quark.cn/s/3bac52e09479

Java + Spring Boot + MyBatis 枚举变量传递给XML映射文件做判断

枚举定义 ReagentStatus.java package com.weiyu.utils.enums;import lombok.Getter;/*** 试剂状态枚举*/ Getter public enum ReagentStatus {// 常规REGULAR,// 少库存LESS_INVENTORY,// 零库存ZERO_INVENTORY,// 将过期WILL_EXPIRE,// 已过期EXPIRED,// 已注销LOGGED,// 全…

华为云Flexus+DeepSeek征文 | 华为云CCE容器高可用部署Dify高可用版实测:从0到1的高可靠应用实践

引言 随着大语言模型&#xff08;LLM&#xff09;技术的爆发&#xff0c;如何快速构建具备高可用、弹性扩展能力的AI应用开发平台&#xff0c;成为企业数字化转型的关键命题。华为云依托其云原生基础设施&#xff0c;推出CCE容器高可用版Dify部署方案&#xff0c;通过“一键部…

c++_cout的理解和使用

问题引入 cout << (uf.is_same_set(x, y)) ? Y : N<<endl; 请问大家&#xff0c;这条语句对吗&#xff1f;&#xff08;这里的uf.is_same_set(x, y)是一个自定义函数&#xff0c;返回bool值&#xff1b;所以不是问题的关键&#xff09;》 答案是这条语句报错了…

山东大学项目实训-创新实训-法律文书专家系统-项目报告(八)

项目实训博客 : 项目后端架构 , 项目的四端交互(前端 ,后端 ,模型端 ,数据库)的开发和维护 , 项目功能总览 作为项目的后端和前端交互功能主要开发者,我需要对项目的四端交互进行开发和维护. 总览: 整体项目结构如图所示: 前后端的交互: 前端封装了request.js : 方便前端…

12.8Java Swing 中的MVC

在 Java Swing 中&#xff0c;MVC 模式被广泛应用。例如&#xff0c;JTable、JList 等组件都采用了这种模式。通常&#xff1a; 模型&#xff1a;实现特定的 Swing 模型接口&#xff08;如 TableModel、ListModel&#xff09;。视图&#xff1a;是 Swing 组件本身&#xff08;…

DDS(Data Distribution Service)

DDS&#xff08;Data Distribution Service&#xff09;是一种以数据为中心的发布/订阅&#xff08;DCPS&#xff09;通信中间件协议栈标准&#xff08;由OMG组织维护&#xff09;。它专为高性能、可预测、实时、可靠的分布式系统设计&#xff0c;广泛应用于国防、航空航天、工…

python爬虫关于多进程,多线程,协程的使用

简介&#xff1a; python其实没有真正意义的多线程&#xff0c;因为有GIL锁存在&#xff0c;但是python3.13去掉GIL锁&#xff0c;有两个版本&#xff0c;python3.13t和python3.13&#xff0c;python3.13去掉GIL锁相当于python底层大规模改变&#xff0c;肯定会影响一些库的使…

java 设计模式_行为型_23状态模式

23.状态模式 Java中的状态设计模式是一种软件设计模式&#xff0c;当对象的内部状态更改时&#xff0c;该模式允许对象更改其行为。状态设计模式通常用于以下情况&#xff1a;对象取决于其状态&#xff0c;并且在运行期间必须根据其内部状态更改其行为。状态设计模式是许多行为…

Flink CDC MySQL 时区相差 8 小时问题优雅解决方式

Flink CDC MySQL 时区相差 8 小时问题解析 代码运行环境 Flink 1.15 + FlinkCDC 2.4.0 + jdk1.8 +springboot 2.31、原因分析 Flink CDC 底层使用 Debezium 连接器来捕获 MySQL 的数据变更,而 Debezium 在解析 MySQL 的 binlog 日志时,默认使用 UTC 时区来处理时间字段。若…

如何在 MX Linux 上安装 Blender CAD 软件

Blender 是一款免费且开源的 CAD 软件,可用于 3D 动画、建模、动态图形、纹理处理、电脑游戏、UV 展开等。同时它也是一款专业的开源程序,是商业软件(如 Maya 或 Cinema 4D)的替代品,支持导入或导出标准格式,如 OBJ、FBX、3DS、PLY 和 STL。Blender 还可以作为视频编辑软…