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
英文地址,請注明出處:http://en.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 還可以作為視頻編輯軟…