關於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)的聯合身份。在這種情況下,終端使用者與他們的身份提供者進行對話,並且身份提供者生成一個加密簽名的令牌,並將其交給應用程式以對使用者進行身份驗證。該應用程式信任身份提供者。
工作流程圖:
3:OAuth2 元件
①:Resource Owner: 資源擁有者。
②:Resource Server: 提供資源訪問的資源伺服器
③:Client: 訪問伺服器資源的客戶端
④:Authorization Server: 認證伺服器
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的公 鑰/私鑰對來簽名,防⽌被篡改。
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官網 便有展示的例子:
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
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
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
A:使用者傳送攜帶客戶端憑證、授權型別(client_credentials)的請求到Auth Server。
B:服務端進行校驗之後,不通過則返回錯誤,通過則發放token(不返回refresh_token)。
5.4:Implicat Grant Type
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 | 可選項,表示客戶端的當前狀態,可以指定任意值,認證伺服器會原封不動地返回這個值。 |