理解OAuth2.0認證與客戶端受權碼模式詳解

1、什麼是OAuth協議

    OAuth 協議爲用戶資源的受權提供了一個安全又簡易的標準。與以往的受權方式不一樣之處是 OAuth的受權不會使第三方觸及到用戶的賬號信息(如用戶名與密碼),即第三方無需使用用戶的用戶名與密碼就能夠申請得到該用戶資源的受權,所以 OAuth是安全的。OAuth 是 Open Authorization 的簡寫web

    OAuth 自己不存在一個標準的實現,後端開發者本身根據實際的需求和標準的規定實現。其步驟通常以下:json

  1. 第三方要求用戶給予受權後端

  2. 用戶贊成受權api

  3. 根據上一步得到的受權,第三方向認證服務器請求令牌(token緩存

  4. 認證服務器對受權進行認證,確認無誤後發放令牌安全

  5. 第三方使用令牌向資源服務器請求資源服務器

  6. 資源服務器使用令牌向認證服務器確認令牌的正確性,確認無誤後提供資源微信

2、OAuth2.0是爲了解決什麼問題?

    任何身份認證,本質上都是基於對請求方的不信任所產生的。同時,請求方是信任被請求方的,例如用戶請求服務時,會信任服務方。因此,身份認證就是爲了解決身份的可信任問題。app

    在OAuth2.0中,簡單來講有三方:用戶(這裏是指屬於服務方的用戶)、服務方(如微信、微博等)、第三方應用編輯器

  1. 服務方不信任用戶,因此須要用戶提供密碼或其餘可信憑據

  2. 服務方不信任第三方應用,因此須要第三方提供自已交給它的憑據(如微信受權的code,AppID等)

  3. 用戶部分信任第三方應用,因此用戶願意把自已在服務方里的某些服務交給第三方使用,但不肯意把自已在服務方的密碼等交給第三方應用

3、OAuth2.0成員和受權基本流程

3.1 OAuth2.0成員

  1. Resource Owner(資源擁有者:用戶)

  2. Client (第三方接入平臺:請求者)

  3. Resource Server (服務器資源:數據中心)

  4. Authorization Server (認證服務器)

3.2 OAuth2.0基本流程


    步驟詳解:

  1. Authorization Request, 第三方請求用戶受權

  2. Authorization Grant,用戶贊成受權後,會從服務方獲取一次性用戶受權憑據(如code碼)給第三方

  3. Authorization Grant,第三方會把受權憑據以及服務方給它的的身份憑據(如AppId)一塊兒交給服務方的向認證服務器申請訪問令牌

  4. Access Token,認證服務器覈對受權憑據等信息,確認無誤後,向第三方發送訪問令牌Access Token等信息

  5. Access Token,經過這個Access TokenResource Server索要數據

  6. Protected Resource,資源服務器使用令牌向認證服務器確認令牌的正確性,確認無誤後提供資源

    這樣服務方,一能夠肯定第三方獲得了用戶對這次服務的受權(根據用戶受權憑據),二能夠肯定第三方的身份是能夠信任的(根據身份憑據),因此,最終的結果就是,第三方順利地從服務方獲取到了這次所請求的服務
    從上面的流程中能夠看出,
OAuth2.0完整地解決了用戶服務方第三方 在某次服務時這三者之間的信任問題

4、第三方客戶端受權碼模式詳解

4.1 受權碼模式

    客戶端必須獲得用戶的受權(authorization grant),才能得到令牌(access token)。OAuth 2.0定義了四種受權方式:

  1. 受權碼模式(authorization code

  2. 簡化模式(implicit

  3. 密碼模式(resource owner password credentials

  4. 客戶端模式(client credentials

    受權碼模式(authorization code)是功能最完整、流程最嚴密的受權模式。它的特色就是經過客戶端的後臺服務器與"服務提供商"的認證服務器進行互動。

4.2 受權碼流程圖及步驟

    


    它的步驟以下:

  1. 用戶訪問客戶端,後者將前者導向認證服務器

  2. 用戶選擇是否給予客戶端受權

  3. 假設用戶給予受權,認證服務器將用戶導向客戶端事先指定的重定向URI,同時附上一個受權碼

  4. 客戶端收到受權碼,附上早先的重定向URI,向認證服務器申請令牌。這一步是在客戶端的後臺的服務器上完成的,對用戶不可見

  5. 認證服務器覈對了受權碼和重定向URI,確認無誤後,向客戶端發送訪問令牌(access token)和更新令牌(refresh token)等

4.3 步驟詳情及所需參數

4.3.1 步驟1: 客戶端申請認證的URI

    包含如下參數:

  • response_type:表示受權類型,必選項,此處的值固定爲"code"

  • client_id:表示客戶端的ID,必選項。(如微信受權登陸,此ID是APPID

  • redirect_uri:表示重定向URI,可選項

  • scope:表示申請的權限範圍,可選項 state:表示客戶端的當前狀態,能夠指定任意值,認證服務器會原封不動地返回這個值

    示例:

GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
HTTP/1.1 Host: server.example.com

    對比網站應用微信登陸:請求CODE

https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

4.3.2 步驟3:認證服務器迴應客戶端的URI

    包含如下參數:

  • code:表示受權碼,必選項。該碼的有效期應該很短,一般設爲10分鐘,客戶端只能使用該碼一次,不然會被受權服務器拒絕。該碼與客戶端ID和重定向URI,是一一對應關係。

  • state:若是客戶端的請求中包含這個參數,認證服務器的迴應也必須如出一轍包含這個參數。

    示例:

HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
&state=xyz

4.3.3 步驟4:客戶端向認證服務器申請令牌的HTTP請求

    包含如下參數:

  • grant_type:表示使用的受權模式,必選項,此處的值固定爲"authorization_code"。

  • code:表示上一步得到的受權碼,必選項。

  • redirect_uri:表示重定向URI,必選項,且必須與A步驟中的該參數值保持一致。

  • client_id:表示客戶端ID,必選項。

    示例:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

    對比網站應用微信登陸:經過code獲取access_token

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

4.3.4 步驟5:認證服務器發送的HTTP回覆

    包含如下參數:

  • access_token:表示訪問令牌,必選項。

  • token_type:表示令牌類型,該值大小寫不敏感,必選項,能夠是bearer類型或mac類型。

  • expires_in:表示過時時間,單位爲秒。若是省略該參數,必須其餘方式設置過時時間。

  • refresh_token:表示更新令牌,用來獲取下一次的訪問令牌,可選項。

  • scope:表示權限範圍,若是與客戶端申請的範圍一致,此項可省略。

    示例:

 HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}

    從上面代碼能夠看到,相關參數使用JSON格式發送(Content-Type: application/json)。此外,HTTP頭信息中明確指定不得緩存。

    對比網站應用微信登陸:返回樣例

{ 
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE",
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

4.4 更新令牌


    若是用戶訪問的時候,客戶端的訪問令牌access_token已通過期,則須要使用更新令牌refresh_token申請一個新的訪問令牌。
    客戶端發出更新令牌的HTTP請求,包含如下參數:

  • granttype:表示使用的受權模式,此處的值固定爲"refreshtoken",必選項。

  • refresh_token:表示早前收到的更新令牌,必選項。

  • scope:表示申請的受權範圍,不能夠超出上一次申請的範圍,若是省略該參數,則表示與上一次一致。

    示例:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA

微信刷新Token:

https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN

(完)

參考文檔一:理解OAuth 2.0
參考文檔二:Oauth2.0原理
OAuth 受權的工做原理是怎樣的?足夠安全嗎?

喜歡,在看

本文分享自微信公衆號 - JAVA樂園(happyhuangjinjin88)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索