大話Oauth2.0,從概念到實踐 (一)

Oauth2.0本身:

Oauth2.0是一種授權協議,當然也歸屬爲安全協議的範疇,在實際執行的時候就是保護互聯網中不斷增長的大量WEB API的安全訪問。OAuth2.0共包含四種角色,分別是資源所有者、第三方應用(也稱爲客戶端client)、授權服務器和資源服務器。如下圖所示,某公司A開發了一個微信小程序(第三方應用)可以幫助我(資源所有者)美化微信服務器(資源服務器)上面的頭像,我在用這個微信小程序開發的美化頭像功能的時候,首先要給微信小程序授權(授權服務器),這個微信小程序才能訪問我的頭像,實際上訪問的時候微信小程序就是通過WEB API來調用的。授權的過程中我是不可能把我的賬號密碼給它的,這樣的前提下就會有另外方式的授權,也就是上面介紹的現在國際通用的標準OAuth2.0。

OAuth2.0協議流程描述了四種角色之間的交互過程,如下圖所示。

上面的序列圖一共分爲以下6個步驟:

(1)第三方應用請求資源所有者授權。

(2)資源所有者同意給第三方應用授權。

(3)第三方應用使用步驟2中獲得的授權,向授權服務器申請令牌。

(4)授權服務器對第三方應用進行認證並確認無誤後,同意發放令牌。

(5)第三方應用使用步驟4中發放的令牌向資源服務器申請獲取資源。

(6)資源服務器確認令牌無誤後,向第三方應用開放資源訪問。

關於更詳細的Oauth2.0流程介紹,也可以參考《架構修煉之道》第2章 "開放之道" 內容。

第三方開發者ISV的實踐:

如果按照開發語言類型來區分可以有JAVA、.net、PHP等不同的ISV應用類型,但語言分類對於授權的場景意義不大,因爲雖然是不同的語言但大家都是遵守Oauth2.0協議。在授權上區分ISV接入流程我們則需要按照ISV應用有無Web Server來區分。有Web Server的歸爲一類,走Server-side flow;沒有Web Serve的歸爲另外一類,走Client-side flow流程。

本文先介紹Server-side flow流程,共包含3個步驟。

步驟一:拼接授權URL

以京東宙斯開放平臺爲例

https://open-oauth.jd.com/oauth2/to_login?app_key=XXXXX&response_type=code&redirect_uri=XXXXX

有三個必填參數,分別是app_key,response_type,redirect_uri,下面是該三個參數的具體含義。

名稱 是否必填 參數值
app_key ISV在宙斯開放平臺創建應用的時候由系統分配
response_type 固定值code,默認採用code換取token的方式
redirect_uri ISV的應用訪問地址,創建應用的時候由ISV配置

PS:左右滑動查看完整列表

注:如果是通過開放平臺直接使用,ISV可以不用拼接該授權URL,會由開放平臺一方的系統自動讀取ISV的應用地址然後拼接好返回給客戶端,後文在平臺一方的實踐介紹中有敘述。

步驟二:引導用戶登錄授權

引導用戶登錄,併爲ISV應用進行授權。

步驟三:獲取CODE

在用戶登錄並點擊授權之後宙斯會將授權碼CODE返回到回調地址上,比如https://redirect_uri?code=CODE&...

ISV獲取到CODE之後就可以執行步驟四。

步驟四:用CODE換取ACCESSTOKEN

https://open-oauth.jd.com/oauth2/access_token?app_key=XXXXX&app_secret=XXXXX&grant_type=authorization_code&code=XXXXX,這裏的code是通過步驟三獲取到的。

名稱 是否必填 參數值
app_key ISV在宙斯開放平臺創建應用的時候由系統分配
app_secret 宙斯開放平臺分配給當前app_key對應的應用的祕鑰
grant_type 固定爲authorization_code
code 步驟三中獲取到的值

PS:左右滑動查看完整列表

返回值示例:

{

access_token: "a3207b6b5ad04249ad1dbf6a98248bea",//所需要的access_token

expires_in: 3600000,//單位ms,該access_token的過期時間

refresh_token: "4ecbbab0e9e443159c518da1d10741ad"//再不需要用戶重新授權的情況下,用於獲取新的access_token

}

access_token是有有效期的,這一點是從安全角度來考慮的,因爲如果access_token沒有時效性,一旦泄露則會被攻擊者長期使用。好比我們的個人密碼需要定期修改一樣。比如筆者跟公司簽訂了五年期的合同,在這個五年時間內公司要求我們的內部ERP系統的密碼需要三個月更新一次,這樣避免了密碼一旦泄露造成了長期的安全風險。在訂購類型的第三方IT工具類應用中access_token是用戶授權之後ISV的應用才能獲取到的,比如用戶購買了該ISV的一款SASS軟件爲期6個月。如果這6個月時間內出於安全考慮需要更新access_token的值,肯定不能讓用戶再授權一次,這樣體驗非常不友好。此時refresh_token就派上了用場,ISV可以利用refresh_token去請求開放平臺獲取新的access_token的值。

當用戶授權ISV之後會獲取到一個accestoken,對於ISV來講accestoken相當於登錄成功了ISV軟件之後的PIN。此時ISV需要將這個用戶的accestoken會話保存下來,可以加密存儲到cookie中,也可以放到ISV軟件服務端的session中。ISV軟件後續訪問平臺的接口要求必須都要有該accestoken,這樣會話狀態被保存下來之後則會使得ISV應用調用平臺接口更加的便利,實際上相當於用戶登錄了一個普通的WEB應用之後,每次這個WEB應用服務端程序都能獲取到該用戶的會話信息一樣。

平臺一方的實踐:

我作爲一個用戶需要授權給我當前將要使用的軟件服務商,這樣軟件服務商纔可以被允許去訪問我的數據。理論上我是需要每次都進行授權動作才能完成軟件的使用,那麼我們平時會發現比如在微信中使用第三方小程序的時候我只在第一次訪問的時候進行了授權動作,以後使用的時候並沒有要求我再次進行授權,這是如何實現的呢。再比如下圖所示,在用戶點擊立即使用的時候也會遇到同樣的場景:初次使用和再次使用。

這就需要作爲平臺一方來實現控制邏輯,同時這個也建立在用戶在平臺使用的基礎之上。平臺一方在第一次用戶授權之後會按照Oauth2.0的規範生成一個accesstoken,隨後將該accesstoken與當前用戶的pin進行綁定存儲到數據庫中,如下圖所示。當然該授權關係是有時效的(這個時效需要依據平臺的實際環境來確定)。當用戶再次來通過平臺去訪問該軟件的時候,平臺會根據當前登錄的用戶pin去判斷先前已經保存的綁定關係,如果有綁定關係則允許用戶直接使用軟件,在返回的startUrl中是一個帶有code的ISV軟件的啓動地址,如果沒有綁定關係則會直接利用第三方開發者已經接入的規範的Oauth2.0協議流程,返回的startUrl中是一個授權的頁面地址,由第三方開發者去引導用戶進行授權。

總結

本文先後從概念到開發者實踐以及平臺一方的實踐去介紹了Oauth2.0。它是一個基於HTTP的協議,如果採用授權碼類型比如本文中所述的Server-side flow則要求必須有Web Server,我們也正是按照該流程去介紹如何實踐的。

 

發佈了87 篇原創文章 · 獲贊 30 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章