SpringCloud-OAuth2(一):基礎篇

竹根七發表於2021-05-24

關於Oauth2 的詳細介紹官網地址:https://developer.okta.com/blog/2017/06/21/what-the-heck-is-oauth

1:什麼是OAuth2

首先,OAuth不是API或服務:它是開放的授權標準,任何人都可以實現。
更具體地說,OAuth是應用程式可用於向客戶端應用程式提供“安全委託訪問”的標準。
OAuth通過HTTPS進行工作,並使用訪問令牌(而不是憑據)對裝置,API,伺服器和應用程式進行授權。

2:為什麼要用OAuth2

OAuth是作為對直接身份驗證模式的響應而建立的。該模式通過HTTP基本身份驗證而聞名,在該系統中,提示使用者輸入使用者名稱和密碼。基本身份驗證仍用作伺服器端應用程式API身份驗證的原始形式:使用者傳送API金鑰ID和密碼,而不是隨每個請求向伺服器傳送使用者名稱和密碼。在使用OAuth之前,網站會提示您直接在表單中輸入您的使用者名稱和密碼,然後他們將以您的身份登入到您的資料(例如您的Gmail帳戶)。這通常稱為密碼反模式。
為了為Web建立更好的系統,建立了用於單點登入(SSO)的聯合身份。在這種情況下,終端使用者與他們的身份提供者進行對話,並且身份提供者生成一個加密簽名的令牌,並將其交給應用程式以對使用者進行身份驗證。該應用程式信任身份提供者。

工作流程圖:
drawing

3:OAuth2 元件

①:Resource Owner: 資源擁有者。

②:Resource Server: 提供資源訪問的資源伺服器

③:Client: 訪問伺服器資源的客戶端

④:Authorization Server: 認證伺服器

drawing

4:OAuth Token

訪問令牌是客戶端用來訪問資源伺服器(API)的令牌。

①:access_token
存在過期時間,可能是12個小時,由Authorization Server 頒發並決定它的過期時間。

②:refresh_token
一般比access_token的過期時間長點,用來重新獲取access_token。


預設的Oauth Token 是UUID 形式存在的。當然我們也可以將 token 的結構以JWT的形式頒發給客戶端。

4.1:JWT簡單介紹

什麼是JWT?
JSON Web Token(JWT)是⼀個開放的⾏業標準(RFC 7519),它定義了⼀種簡介的、⾃包含的協議
格式,⽤於 在通訊雙⽅傳遞json物件,傳遞的資訊經過數字簽名可以被驗證和信任。JWT可以使⽤
HMAC演算法或使⽤RSA的公 鑰/私鑰對來簽名,防⽌被篡改。

drawing

JWT 通常分為三部分,中間用 . 隔開,分別為 header、payload、signature。


①:header
頭部包括令牌的型別(即JWT)及使⽤的雜湊演算法(如HMAC SHA256或RSA),例如:

{
 "alg": "HS256",
 "typ": "JWT"
}

②:payload
第⼆部分是負載,內容也是⼀個json物件,它是存放有效資訊的地⽅,它可以存放jwt提供的現成
欄位,⽐ 如:iss(簽發者),exp(過期時間戳), sub(⾯向的⽤戶)等,也可⾃定義欄位。 此部
分不建議存放敏感資訊,因為此部分可以解碼還原原始內容。

{
 "expire": "1234567890",
 "username": "ZhangSan",
 "role":["admin"]
}

③:Signature
第三部分是簽名,此部分⽤於防⽌jwt內容被篡改。 這個部分使⽤base64url將前兩部分進⾏編
碼,編碼後使⽤點(.)連線組成字串,最後使⽤header中宣告 簽名演算法進⾏簽名。

HMACSHA256(
 base64UrlEncode(header) + "." +
 base64UrlEncode(payload),
 secret)

開啟 jwt.io官網 便有展示的例子:
drawing

4.2:JWT 與 session 的區別

在很多情況下,我們會採用session共享的技術方案去解決叢集條件下登入狀態的問題。比如Spring-Session框架就很好解決了這個問題。
那麼為什麼還需要JWT呢?

區別一:是否需要儲存在服務端?

session共享需要存放在redis或者其他分散式快取中,以保證每個服務節點能共享session。
而JWT並不需要儲存在服務端,客戶端可以將token存放在Cookie或者LocalStorage中,並在傳送請求的時候帶上就行,服務端只是將JWT解密出來並校驗而已。

區別二:對於跨系統的sso誰更出色?

個人認為是JWT更出色,因為A系統頒發的token,B系統只需要具備識別token的機制即可,不需要和A系統進行互動即可認證(前提是A、B系統的使用者資料需同步)。

5:OAuth2 四種授權模式

5.1:Authrization Code Grant Type

drawing

A:使用者傳送請求到 Auth Server,請求需攜帶客戶端憑證、redirect_uri、授權型別(code) 資訊。
B:Auth Server校驗客戶端憑證是否通過,通過則調到登入頁,不通過則返回錯誤。
C:使用者在登入頁輸入使用者名稱+密碼,再請求到 Auth Server 。
D:Auth Server校驗使用者名稱+密碼是否正確,不正確返回錯誤,正確調到redirect_uri 地址並在地址上拼接上code。
E:使用者拿到 code 呼叫/oauth/token 介面帶上code作為引數,以授權碼模式(authorization_code)換取 token。
F:Auth Server 對code進行校驗(code具備過期時間,且只能使用一次,無論換token是否成功或者失敗),失敗返回錯誤,成功則發放token。
G:拿到token之後使用者便是一個Resource Owner,可以帶上token 訪問自己的資源。如訪問屬於自己的使用者資料。
H:使用者對token進行鑑權,通過之後返回正確的響應體,否則返回錯誤。

5.2:Password Grant Type

drawing

A:使用者傳送攜帶客戶端憑證、使用者名稱密碼、授權型別(password) 資訊的請求到Auth Server。
B:Auth Server 先校驗客戶端憑證是否正確,不正確返回錯誤。
C:再校驗使用者名稱密碼是否合法,不合法返回錯誤。
D:B、C全部通過,Auth Server 發放token給客戶端。
E:拿到token之後使用者便是一個Resource Owner,可以帶上token 訪問自己的資源。如訪問屬於自己的使用者資料。
F:使用者對token進行鑑權,通過之後返回正確的響應體,否則返回錯誤。

5.3:Client Credentials Grant Type

drawing

A:使用者傳送攜帶客戶端憑證、授權型別(client_credentials)的請求到Auth Server。
B:服務端進行校驗之後,不通過則返回錯誤,通過則發放token(不返回refresh_token)。

5.4:Implicat Grant Type

drawing

A:使用者傳送請求到 Auth Server,請求需攜帶客戶端憑證、redirect_uri、授權型別(token) 資訊。
B:Auth Server 對客戶端憑證進行校驗,失敗返回錯誤,成功重定向到授權頁。
C:使用者選擇具體的scope,點選 Approval/Deny 按鈕,併傳送認證請求到 Auth Server。
D:使用者若是點選了Deny 再傳送請求,服務端返回錯誤資訊,使用者若是點了Approval 按鈕,則返回可用的token(token未失效則是發放舊的token)。


授權碼模式(authorization_code)和簡易模式(implicat)中引數解析:

名稱 作用
response_type 表示授權型別,必選項,authorization_code 模式值為"code",implicat模式值為"token"。
client_id 表示客戶端的ID,必選項。
redirect_uri 表示重定向URI,可選項。
scope 表示申請的許可權範圍,可選項。
state 可選項,表示客戶端的當前狀態,可以指定任意值,認證伺服器會原封不動地返回這個值。

相關文章