ttps://medium.com/@robert.broeckelmann/saml2-vs-jwt-understanding-openid-connect-part-2-f361ca867baa
這篇文章繼續(xù)我們對OpenID連接(OIDC)的討論。我們來看看OIDC規(guī)范定義的三個(gè)身份驗(yàn)證流之一——授權(quán)代碼授權(quán)流。
1、OIDC身份驗(yàn)證流
OAuth2定義了授權(quán)授權(quán)和擴(kuò)展授權(quán)(Authorization Grants and Extension Grants),OIDC規(guī)范定義了認(rèn)證流。概念是相似的。該規(guī)范定義了三個(gè)認(rèn)證流;這些流的不同之處包括傳遞給OP的參數(shù)、響應(yīng)的內(nèi)容以及如何處理響應(yīng)。對授權(quán)端點(diǎn)的請求(以及身份驗(yàn)證流詳細(xì)信息)之間的區(qū)別是return_type參數(shù)。該參數(shù)有幾個(gè)有效值,定義在OAuth2規(guī)范和OAuth2多響應(yīng)類型規(guī)范之間:
Authorization Code Flow: code
Implicit Flow: id_token
Implicit Flow: id_token token
Hybrid Flow: code id_token
Hybrid Flow: code token
Hybrid Flow: code id_token token
那么,這一切意味著什么呢?當(dāng)您在response_type參數(shù)中看到“code”值時(shí),授權(quán)端點(diǎn)響應(yīng)將返回授權(quán)代碼。只要在response_type參數(shù)中包含了“id_token”,就會(huì)在響應(yīng)中包含一個(gè)id_token。當(dāng)response_type參數(shù)中包含“token”時(shí),來自授權(quán)端點(diǎn)的響應(yīng)中將包含一個(gè)access_token。這些細(xì)節(jié)會(huì)影響響應(yīng)的結(jié)構(gòu),依賴方(RP、客戶)(Relying Party (RP, Client))下一步采取什么處理步驟,以及可以處理什么用例,如下所示。請注意,
OIDC授權(quán)碼流直接擴(kuò)展了OAuth2授權(quán)碼授權(quán)。OIDC隱式流和OIDC混合流是對OIDC授權(quán)碼流的擴(kuò)展。
OIDC定義的授權(quán)碼response_type與OAuth2規(guī)范定義的同名response_type不同。
本文中使用的所有示例請求和響應(yīng)都是OIDC規(guī)范中給出的示例的變體。
授權(quán)碼流(OIDC v1.0規(guī)范,章節(jié)3.1):這是OAuth2授權(quán)碼授權(quán)的OIDC版本。此流的response_type設(shè)置為“code”。這里給出的示例利用授權(quán)代碼Grant中的所有可用功能來完成:
終端用戶認(rèn)證
中繼方(客戶端、應(yīng)用程序)Relaying Party (Client, application)的身份驗(yàn)證(可選)。
中繼方(RP) Relaying Party (RP)看不到最終用戶的憑據(jù)(密碼)
用戶代理User Agent 看不到訪問令牌或ID令牌Access Token or ID Token
SSO RP
獲取多個(gè)訪問令牌或多個(gè)范圍訪問令牌。
使用訪問令牌對API提供者(資源服務(wù)器,Resource Server)進(jìn)行API(資源)調(diào)用。

下面將遍歷上圖中的步驟。最終用戶通過在web瀏覽器中輸入網(wǎng)站地址或類似的操作(圖中沒有顯示)來啟動(dòng)應(yīng)用程序登錄過程。然后瀏覽器(用戶代理)向RP發(fā)送一個(gè)請求,RP攔截該請求并發(fā)現(xiàn)它不是經(jīng)過身份驗(yàn)證的會(huì)話的一部分——同樣,在圖中也沒有顯示(規(guī)范沒有涵蓋這一部分)。
(1)身份驗(yàn)證請求
RP將用戶代理重定向到OpenID提供者(OP)——步驟(A)。結(jié)果請求看起來像這樣:
GET /oidc/authorize?
response_type=code
&scope=openid%20profile%20email
&client_id=s6BhdRkqt3
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1
Host: server.example.com
identity provider (OP) 將重定向用戶代理登錄工作流是由OP -步驟(B)。身份驗(yàn)證是如何工作的詳細(xì)信息不在OIDC規(guī)范的范圍。我們稱之為OIDC身份驗(yàn)證協(xié)議,但它沒有定義如何驗(yàn)證用戶的詳細(xì)信息。這與SAML2 Web Browser SSO Profile的工作方式?jīng)]有什么不同——用戶的實(shí)際身份驗(yàn)證可以是各種各樣的機(jī)制,這些機(jī)制依賴于身份提供者(OP)功能。身份驗(yàn)證工作流還可以包含一個(gè)檢查,允許最終用戶同意RP對其擁有的資源的訪問(授權(quán)訪問被授予Resource上的RP)。
(2)成功的身份驗(yàn)證響應(yīng)
成功的身份驗(yàn)證后,OP將用戶重定向回授權(quán)端點(diǎn)authorization endpoint ,使用會(huì)話跟蹤信息集(可能是會(huì)話cookie的形式,依賴于實(shí)現(xiàn))。授權(quán)端點(diǎn)將返回一個(gè)HTTP重定向(帶有授權(quán)碼)到RP URL,它看起來類似于以下步驟(C):
HTTP/1.1 302 Found
Location: https://client.example.org/cb?
code=SplxlOBeZQQYbYS6WxSbIA
&state=af0ifjsldkj
因此,用戶代理向RP發(fā)送如下請求:
GET https://client.example.org/cb?
code=SplxlOBeZQQYbYS6WxSbIA
&state=af0ifjsldkj
(3)身份驗(yàn)證錯(cuò)誤
如果在身份驗(yàn)證和同意階段(或返回授權(quán)代碼之前的任何其他階段)發(fā)生錯(cuò)誤,授權(quán)端點(diǎn)將返回類似如下的錯(cuò)誤:
HTTP/1.1 302 Found
? Location: https://client.example.org/cb?
? ? error=invalid_request
? ? &error_description=
? ? ? Unsupported%20response_type%20value
? ? &state=af0ifjsldkj
(4)令牌的請求
此時(shí),RP已經(jīng)收到了授權(quán)代碼,但還沒有看到最終用戶的密碼(或其他憑據(jù))。現(xiàn)在,RP需要從令牌端點(diǎn)獲取訪問令牌、ID令牌Access Token, ID Token和其他信息。因此,RP向令牌端點(diǎn) token endpoint發(fā)送類似如下的請求——步驟(D):
POST /oidc/token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=SplxlOBeZQQYbYS6WxSbIA&
redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb&
client_id=s6BhdRkqt3&
client_secret=blah_blah_blah_1234
client_secret參數(shù)只需要在RP是一個(gè)機(jī)密客戶端時(shí)存在(就像一般的OAuth2授權(quán)碼授予一樣)。在OIDC規(guī)范第9節(jié)中描述了驗(yàn)證RP到令牌端點(diǎn)的替代方法;OAuth2規(guī)范也支持基本身份驗(yàn)證(它是首選的方法)。
(5)令牌響應(yīng)
來自授權(quán)代碼流的令牌端點(diǎn) token endpoint 的響應(yīng)類似于以下步驟(E)。
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
“access_token”: “SlAV32hkKG”,
“token_type”: “Bearer”,
“refresh_token”: “8xLOxBtZp8”,
“expires_in”: 3600,
“id_token”: “eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc
yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5
NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ
fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz
AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q
Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ
NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd
QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS
K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4
XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg”
}
(6)驗(yàn)證令牌
現(xiàn)在,ID Token(上面的id_token屬性)必須根據(jù)OIDC規(guī)范的3.1.3.7節(jié)進(jìn)行驗(yàn)證——步驟(F)——不要跳過這一部分,這會(huì)影響安全性。對于這個(gè)認(rèn)證流,ID令牌 ID Token將包含一個(gè)at_hash(訪問令牌散列) (Access Token hash) 屬性,可以用來驗(yàn)證訪問令牌;這是可選的,但推薦的步驟(G)。
在OIDC場景下,RP上使用ID Token進(jìn)行認(rèn)證,使用Access Token進(jìn)行認(rèn)證:
調(diào)用資源服務(wù)器(在我們的例子中是API提供者)
userinfo 端點(diǎn)處獲取信息(可選)
這與oauth2工作方式不一樣。
(7)訪問令牌的范圍
現(xiàn)在,如果訪問令牌有一個(gè)受眾概念(不透明令牌可能不是這樣),那么RP可能需要唯一的訪問令牌來訪問UserInfo端點(diǎn)和訪問資源服務(wù)器。如果是這種情況,那么可以使用相同的授權(quán)代碼對令牌端點(diǎn)進(jìn)行第二次調(diào)用,請求資源服務(wù)器的受眾提供第二個(gè)訪問令牌——假設(shè)OP已配置為允許這樣的訪問。另一個(gè)潛在的方法是利用一個(gè)作用域的訪問令牌,支持多個(gè)觀眾——JWT允許這個(gè)——但是,OP必須支持和有潛在的安全問題,演員的數(shù)量可以做一些有趣的事情和你的身份令牌增加(因此,增加風(fēng)險(xiǎn))。
接下來,如果RP需要額外的要求,它可以聯(lián)系OP的端點(diǎn)用戶信息獲取如前所述,步驟(H) & (I)。有趣的是,RP的 ID Token ,它可以包含任何聲稱,可能是用戶信息返回的端點(diǎn)。但是,OP供應(yīng)商傾向于對這個(gè)特性的靈活性施加一些限制。
(8)呼叫資源服務(wù)器
接下來,RP可以訪問資源的資源服務(wù)器(讓我們稱之為一個(gè)API在一個(gè)API提供者)通過調(diào)用API的訪問令牌授權(quán)頭我們以前探索——一步(J)。在理解OAuth2帖子,假設(shè)訪問令牌是一個(gè)JWT令牌;JWT規(guī)范定義了如何在資源服務(wù)器(API提供者)上驗(yàn)證訪問令牌。如果Access令牌是不透明的令牌,則資源服務(wù)器必須使用規(guī)范之外定義的機(jī)制(可能依賴于實(shí)現(xiàn))與OP通信。2015年10月,發(fā)布了OAuth 2.0 Token Introspection (RFC 7662),它“定義了一種方法,讓受保護(hù)的資源可以查詢OAuth 2.0授權(quán)服務(wù)器,以確定OAuth 2.0令牌的活動(dòng)狀態(tài),并確定有關(guān)該令牌的元信息。”基本上,它定義了一個(gè)授權(quán)服務(wù)器端點(diǎn),該端點(diǎn)可以驗(yàn)證一個(gè)令牌并檢索有關(guān)令牌的信息(令牌內(nèi)省端點(diǎn))。OIDC UserInfo端點(diǎn)和這個(gè)新端點(diǎn)之間有一些重疊,但是OAuth2令牌內(nèi)省端點(diǎn)提供了驗(yàn)證不透明訪問令牌的能力(盡管這不是它的主要目的)。但是訪問令牌被驗(yàn)證了,這個(gè)步驟必須在請求處理可以在資源服務(wù)器(API提供者)-步驟(K)上進(jìn)行之前完成。
最后,資源服務(wù)器可以將收到的訪問令牌傳遞到用戶信息端點(diǎn)獲取ID標(biāo)記與相關(guān)(允許)申請最終用戶——步驟(L) & (M)。處理才能進(jìn)行API請求和響應(yīng)可以回到RP(作為API的消費(fèi)者在這種情況下)。
下面的序列圖中描述了我們剛剛走過的相同場景。
