徹底搞懂 OAuth2.0
假設(shè)你要開(kāi)發(fā)一個(gè)中醫(yī)問(wèn)診平臺(tái),該平臺(tái)可以根據(jù)用戶的中藥飲片購(gòu)買(mǎi)記錄來(lái)智能地計(jì)算用戶可能具有的中醫(yī)癥狀,并自動(dòng)推薦相關(guān)的中醫(yī)專(zhuān)家。這樣的話,用戶為了使用問(wèn)診服務(wù),就必須讓平臺(tái)讀取自己在藥房上的藥品購(gòu)買(mǎi)記錄。
那么問(wèn)題就來(lái)了,問(wèn)診平臺(tái)怎么樣才能獲得用戶的授權(quán)呢?一般我們想到的是,用戶將自己的藥房用戶名和密碼告訴問(wèn)診平臺(tái),然后問(wèn)診平臺(tái)就可以通過(guò)用戶名和密碼登錄到藥房并讀取用戶的購(gòu)藥記錄。
圖片
這個(gè)方案雖然可行,但存在幾個(gè)明顯的漏洞。首先,問(wèn)診平臺(tái)為了開(kāi)展后續(xù)的服務(wù),會(huì)保存用戶在藥房上的密碼,這樣很不安全;其次,問(wèn)診平臺(tái)擁有了獲取用戶存儲(chǔ)在藥房上所有資料的權(quán)力,用戶沒(méi)法限制問(wèn)診平臺(tái)獲得授權(quán)的范圍和有效期;最后,用戶只有修改密碼,才能收回賦予問(wèn)診平臺(tái)的權(quán)力,但是這樣做會(huì)使得其他所有獲得用戶授權(quán)的類(lèi)似問(wèn)診平臺(tái)的第三方應(yīng)用程序全部失效。而且只要有一個(gè)第三方應(yīng)用程序被破解,就會(huì)導(dǎo)致用戶密碼泄漏,以及所有被密碼保護(hù)的數(shù)據(jù)產(chǎn)生泄漏。
聽(tīng)著是不是很可怕?沒(méi)事的,我們有 OAuth2.0 協(xié)議。與傳統(tǒng)方法相比,OAuth2 協(xié)議具有一系列的優(yōu)勢(shì)。
首先,針對(duì)密碼的安全性,在 OAuth2 協(xié)議中,密碼還是由用戶自己保管,避免了敏感信息的泄露;其次,OAuth2 協(xié)議中所提供的授權(quán)具有明確的應(yīng)用范圍和有效期,用戶可以根據(jù)需要限制問(wèn)診平臺(tái)所獲取授權(quán)信息的作用效果;最后,用戶如果對(duì)自己的密碼等身份憑證信息進(jìn)行了修改,那么只要通過(guò) OAuth2 協(xié)議重新進(jìn)行一次授權(quán)即可,不會(huì)影響到相關(guān)聯(lián)的其他第三方應(yīng)用程序。
圖片
為什么 OAuth2 協(xié)議能有這些優(yōu)勢(shì)呢?這是因?yàn)樗兄膫€(gè)核心的角色,資源、客戶端、授權(quán)服務(wù)器和資源服務(wù)器。
圖片
OAuth2 協(xié)議中把需要訪問(wèn)的接口或服務(wù)統(tǒng)稱為資源(Resource),每個(gè)資源都有一個(gè)擁有者(Resource Owner),也就是案例中的用戶。客戶端是中醫(yī)問(wèn)診平臺(tái),也就是第三方應(yīng)用程序(Third-party Application)。而藥房,在案例中的角色是服務(wù)提供商,服務(wù)提供商中的資源服務(wù)器存放著用戶資源,案例中的用戶購(gòu)藥記錄就是一種用戶資源。而授權(quán)服務(wù)器則對(duì)資源擁有者的身份進(jìn)行認(rèn)證,完成授權(quán)審批流程,并最終頒發(fā)一個(gè)訪問(wèn)令牌(Access Token)。
你一定要注意這個(gè)訪問(wèn)令牌。它是 OAuth2 協(xié)議中非常重要的一個(gè)概念,本質(zhì)上也是一種代表用戶身份的授權(quán)憑證,但與普通的用戶名和密碼信息不同,令牌具有針對(duì)資源的訪問(wèn)權(quán)限范圍和有效期。
{
"access_token": "b7c2c7e0-0223-40e2-911d-eff82d125b80",
"token_type": "bearer",
"refresh_token": "40ee99d5-90f6-43ce-920f-383a619fc806",
"expires_in": 43199,
"scope": "webclient"
}
這段代碼中的 access_token 就是 OAuth2 的令牌,當(dāng)訪問(wèn)每個(gè)受保護(hù)的資源時(shí),用戶都需要攜帶這個(gè)令牌以便進(jìn)行驗(yàn)證。
- 針對(duì) token_type,OAuth2 協(xié)議中有很多中可選的令牌類(lèi)型,包括 bearer 類(lèi)型、mac 類(lèi)型等,這里指定的是最常見(jiàn)的一種類(lèi)型,就是 bearer 類(lèi)型;
- expires_in 屬性用于指定 access_token 的有效時(shí)間,當(dāng)超過(guò)這個(gè)有效時(shí)間的時(shí)候,access_token 將會(huì)自動(dòng)失效。
- refresh_token 的作用在于,當(dāng) access_token 過(guò)期之后,重新下發(fā)一個(gè)新的 access_token;
- scope 指定了可訪問(wèn)的權(quán)限范圍,這里指定的是訪問(wèn) Web 資源的“webclient”。
那這個(gè)令牌到底有什么用呢?最大的用處就是我們可以用令牌來(lái)完成基于 OAuth2 協(xié)議的授權(quán)工作流程。也就是:
圖片
- 客戶端請(qǐng)求用戶的授權(quán),請(qǐng)求中一般包含資源的訪問(wèn)路徑、對(duì)資源的操作類(lèi)型等信息
- 用戶同意給予客戶端授權(quán),并將這個(gè)授權(quán)發(fā)送給客戶端
- 客戶端向授權(quán)服務(wù)器請(qǐng)求訪問(wèn)令牌。此時(shí),客戶端需要向授權(quán)服務(wù)器提供上一步獲取的授權(quán)信息,以及客戶端自身的有效身份憑證
- 授權(quán)服務(wù)器驗(yàn)證通過(guò)后,向客戶端返回訪問(wèn)令牌
- 客戶端攜帶訪問(wèn)令牌訪問(wèn)資源服務(wù)器上的資源。在令牌的有效期內(nèi),客戶端可以多次攜帶令牌去訪問(wèn)資源。
- 資源服務(wù)器驗(yàn)證令牌的有效性以及是否過(guò)期,驗(yàn)證通過(guò)后才能開(kāi)放服務(wù)。
在整個(gè)工作流程中,最為關(guān)鍵的是第二步,只有獲取了這個(gè)授權(quán)之后,客戶端才可以獲取令牌,進(jìn)而憑令牌獲取資源。那么用戶如何才能獲取客戶端授權(quán)呢?在 OAuth 2.0 中,定義了四種授權(quán)方式,即授權(quán)碼模式(Authorization Code)、簡(jiǎn)化模式(Implicit)、密碼模式(Password Credentials)和客戶端模式(Client Credentials):
圖片
授權(quán)碼模式功能最完整,流程也最嚴(yán)密,當(dāng)用戶同意授權(quán)后,授權(quán)服務(wù)器不是馬上返回最終的令牌,而是一個(gè)授權(quán)碼,需要客戶端攜帶授權(quán)碼去換令牌,這就需要客戶端自身具備與授權(quán)服務(wù)器進(jìn)行直接交互的后臺(tái)服務(wù)。
圖片
- 用戶訪問(wèn)客戶端,客戶端會(huì)將用戶導(dǎo)向授權(quán)服務(wù)器。
- 用戶選擇是否給予客戶端授權(quán)。
- 假設(shè)用戶給予授權(quán),授權(quán)服務(wù)器將用戶導(dǎo)回客戶端事先指定的回調(diào)地址,同時(shí)附上一個(gè)授權(quán)碼。
- 客戶端收到授權(quán)碼,并附上回調(diào)地址,向授權(quán)服務(wù)器申請(qǐng)令牌。這一步是在客戶端系統(tǒng)的后臺(tái)服務(wù)上完成的,對(duì)用戶不可見(jiàn)。
- 授權(quán)服務(wù)器核對(duì)授權(quán)碼和回調(diào)地址,確認(rèn)無(wú)誤后,向客戶端發(fā)送訪問(wèn)令牌。
我們?cè)賮?lái)看另一種比較常用的密碼模式。它比較簡(jiǎn)單,也更加容易理解。
圖片
在密碼模式下,用戶向客戶端提供用戶名和密碼,然后客戶端將用戶名和密碼發(fā)給授權(quán)服務(wù)器并請(qǐng)求令牌,授權(quán)服務(wù)器確認(rèn)無(wú)誤后,就會(huì)向客戶端發(fā)放令牌。就目前主流的微服架構(gòu)來(lái)說(shuō),當(dāng)我們發(fā)起 HTTP 請(qǐng)求時(shí),關(guān)注的是如何通過(guò) HTTP 協(xié)議透明而高效的傳遞令牌,授權(quán)碼模式下通過(guò)回調(diào)地址進(jìn)行授權(quán)管理的方式就不是很實(shí)用,密碼模式反而更加簡(jiǎn)潔高效。
OAuth2 中的客戶端模式和簡(jiǎn)化模式因?yàn)樵谌粘i_(kāi)發(fā)過(guò)程中應(yīng)用得不是很多,這里就不詳細(xì)介紹了。
你可能注意到,雖然說(shuō) OAuth2 協(xié)議解決的是授權(quán)問(wèn)題,但它也應(yīng)用到了認(rèn)證的概念,因?yàn)橹挥序?yàn)證了用戶的身份憑證,我們才能完成對(duì)他的授權(quán)。所以說(shuō),OAuth2 實(shí)際上是一款技術(shù)體系比較復(fù)雜的協(xié)議,綜合應(yīng)用了信息摘要、簽名認(rèn)證等安全性手段,并需要提供令牌以及背后的公私鑰管理等功能。