Python-Web開發 OAuth2.0 簡介

  • 常常看到或者用到一些可使用微博、微信、支付寶等帳號登陸的應用,還有一些微博助手、微信公衆號助手、客戶端之類的東西,這些是怎麼作的呢,背後的原理是什麼呢?爲何公衆號配置起來那麼繁瑣呢?什麼是 access token、refresh token?等等,今天咱們來了解下開放式受權模式 OAuth
  • 隨着互聯網的發展,各類應用相互交叉,處處須要用戶登陸,信息安全成爲了避免可迴避的問題,應用須要擴展,用戶須要更好的體驗,信息須要更安全的保障,爲了知足這些需求,互聯網技術不斷推陳出新,從通訊安全,到各類協議框架,有無數的解決方案。
  • OAuth 是什麼

    OAuth 框架提供了一種認證和受權機制,可讓用戶將其受保護的資源受權給其餘應用來訪問或者使用。編程

  • 受權機制至關於你給快遞員一個臨時密碼(受權),快遞員可使用這個密碼打開小區門禁,將快遞送到你家門口,然後臨時密碼將失效(詳見參考連接)
  • 這個例子中,你就是 用戶,小區是 受保護的資源,快遞員是其餘應用(第三方應用)。
  • 若是沒有這個機制:瀏覽器

    • 要麼你就得去小區門口拿快遞,不方便,
    • 要麼就得告訴全部可能給你送快遞的快遞員門禁密碼,不安全

    有了 OAuth 框架(協議),既方便,又安全緩存

  • 角色

    OAuth2.0 實際上就是讓第三方服務得到用戶在資源服務器上的受權的過程,會涉及到 4 種角色安全

    • 資源擁有者(Resource owner),即用戶
    • 認證服務器(Authorization server),用來認證用戶憑證,頒佈受權碼的服務器
    • 資源服務器(Resource Server),存放用戶受保護的資源的服務器
    • 第三方應用(Client),也稱之爲客戶端(後續皆稱 客戶端),須要獲得用戶受權,以便訪問用戶受保護的資源的應用程序

    不是任何客戶端都能獲得受權的,在開通 OAuth 受權以前,須要先到認證服務器或者資源服務器上註冊,註冊成功會獲得 appid 和 app_secret,用來向認證服務器代表應用的身份服務器

    角色之間關聯

    瞭解了 OAuth2.0 框架中的主要角色,有必要了解下角色之間關聯關係微信

    • 認證服務器 和 資源服務器:一般來講,認證服務器和資源服務器同屬於一個服務商,它們就有天生的關聯,並且是內部的安全的,甚至它們能夠部署在同一個服務器(Web 服務器)上
    • 用戶 和 服務商:對於像 Github、微信這樣的知名應用,用戶會主動在這些應用或服務上註冊,填寫的資料信息,設置的暱稱,產生的文章、上傳的照片,等等將成爲用戶的資源,這些資源被存放在資源服務器上
    • 客戶端 和 服務商:客戶端,即第三方應用,要從服務商的資源服務器中獲取數據,給用戶提供額外服務,必須在服務商處註冊,提供應用的基本信息,認證信息,服務域名,申請用戶受權的範圍、甚至企業資質(例如申請微信公衆號的企業服務)等等,申請經過後,服務商會返回 appid 和 app_secret,做爲客戶端和服務商的交互憑證
    • 用戶 和 客戶端:客戶端提供了特別的服務,能夠吸引到用戶,爲了讓用戶體驗更好,引導用戶經過受權的方式,從而獲取受權範圍內的用戶信息,例如 Openid,做爲用戶在客戶端上的惟一標識,從而創建起和用戶的關聯

    至此,四個角色之間的關聯就創建好了,下面開始介紹具體的受權方式網絡

  • 基本受權流程

     

  •  

     

  • 沒有比圖更能說明白流程的,借用 RFC6749 文檔app

    受權流程圖
    • A 客戶端,向用戶發出受權請求
    • B 用戶贊成或者拒絕客戶端的受權請求,假設是贊成
    • C 客戶端拿着用戶的受權請求認證服務器作認證
    • D 若是 C 經過認證,認證服務器將返回 Access Token,便可以訪問資源的令牌
    • E 客戶端使用 Access Token 請求資源服務器上的資源
    • F 資源服務器驗證了 Access Token 後,返回受保護的資源

    流程中最核心的是讓客戶端得到 Access Token,以後在訪問受保護資源時,就不須要用戶反覆受權了框架

    Access Token 顯然不是用戶在資源服務器上的密碼,是有認證服務器頒發的,那麼也能夠被銷燬加密

    Access Token 和以前課程中的 JWT 是相似的,實際上 JWT 是 OAuth 認證的一個特例

    受權模式

    根據受權流程,OAuth2.0 定義了 4 種針對不一樣應用場景的受權模式

    • 受權碼模式(authorization code)
    • 簡化模式(implicit)
    • 密碼模式(resource owner password credentials)
    • 客戶端模式(client credentials)

    受權碼模式

    受權碼模式是最完整,安全性最高的受權模式,也是最經常使用的一種模式,其特色是經過客戶端的後臺服務器與認證服務器交互,如圖:

     

     

    受權碼模式流程圖

    注意:上圖中的步驟 A, B, C 在經過用戶代理端( User-Agent 通常指瀏覽器)時,被拆分紅了兩部分

    • A 用戶訪問客戶端的客戶端,後者將前者導向認證服務器
    • B 用戶肯定是否受權給客戶端
    • C 假設用戶給予受權,認證服務器將用戶導向客戶端事先指定的"重定向URI"(Redirection URI),同時附上一個受權碼
    • D 客戶端收到受權碼,經過後臺服務器,附上早先的"重定向URI",向認證服務器申請令牌。這一步對用戶不可見
    • E 認證服務器覈對了受權碼和重定向URI,確認無誤後,向客戶端發送訪問令牌(access token)和更新令牌(refresh token)

    接下來講明一下過程當中所包含一下參數

    不一樣認證服務器上的參數名稱有可能不一樣,但含義相同,例如 client_id 通常被 appid 代替

    步驟 A,客戶端申請認證的 URI,包含如下參數:

    • response_type:表示受權類型,必選項,此處的值固定爲 code,由於須要先獲取受權碼
    • client_id:表示客戶端的ID,必選項,是在認證服務器分配給客戶端的id,即 appid
    • redirect_uri:表示重定向URI,可選項
    • scope:表示申請的權限範圍,可選項
    • state:表示客戶端的當前狀態,能夠指定任意值,認證服務器會原封不動地返回這個值

    步驟 C,認證服務器迴應的 URI,包含如下參數:

    • code:表示受權碼,必選項。該碼的有效期應該很短,一般設爲 10 分鐘,客戶端只能使用該碼一次,不然會被認證服務器拒絕。該碼與客戶端 ID 和重定向 URI,是一一對應關係
    • state:若是客戶端的請求中包含這個參數,認證服務器的迴應也必須如出一轍包含這個參數

    步驟 D,客戶端向認證服務器申請令牌的 HTTP 請求,包含如下參數:

    • grant_type:表示使用的受權模式,必選項,此處的值固定爲 authorization_code
    • code:表示上一步得到的受權碼,必選項
    • redirect_uri:表示重定向 URI,必選項,且必須與 A 步驟中的該參數值保持一致
    • client_id:表示客戶端 ID,必選項

    步驟 E,認證服務器發送的 HTTP 響應,包含如下參數:

    • access_token:表示訪問令牌,必選項
    • token_type:表示令牌類型,該值大小寫不敏感,必選項,能夠是bearer類型或mac類型
    • expires_in:表示過時時間,單位爲秒。若是省略該參數,必須其餘方式設置過時時間
    • refresh_token:表示更新令牌,用來獲取下一次的訪問令牌,可選項
    • scope:表示權限範圍,若是與客戶端申請的範圍一致,此項可省略

    認證服務器會以 JSON 的形式返回 access_token 數據,且不容許作緩存,以提升安全性

    簡化模式

    簡化模式不須要經過客戶端後臺服務器,直接在瀏覽器中向認證服務器申請令牌,跳過了受權碼這個步驟,所以得名。全部步驟在瀏覽器中完成,令牌對訪問者是可見的,且客戶端不須要認證,如圖:

     

     

    簡化模式流程圖
    • A 客戶端將用戶導向認證服務器
    • B 用戶決定是否給予客戶端受權
    • C 假設用戶給予受權,認證服務器將用戶導向客戶端指定的重定向URI,並在URI的Hash部分包含了訪問令牌 access_token
    • D 瀏覽器向資源服務器發出請求,其中不包括上一步收到的Hash值
    • E 資源服務器返回一個網頁,其中包含的代碼能夠獲取Hash值中的令牌
    • F 瀏覽器執行上一步得到的腳本,提取出令牌
    • G 瀏覽器將令牌發給客戶端

    接下來講明一下過程當中所包含一下參數

    步驟 A,客戶端發送 HTTP 請求,包含的參數:

    • response_type:表示受權類型,此處的值固定爲 token,必選項
    • client_id:表示客戶端的ID,必選項
    • redirect_uri:表示重定向的URI,可選項
    • scope:表示權限範圍,可選項
    • state:表示客戶端的當前狀態,能夠指定任意值,認證服務器會原封不動地返回這個值

    步驟 C,認證服務器迴應客戶端的 URI,包含如下參數:

    • access_token:表示訪問令牌,必選項。
    • token_type:表示令牌類型,該值大小寫不敏感,必選項
    • expires_in:表示過時時間,單位爲秒。若是省略該參數,必須其餘方式設置過時時間
    • scope:表示權限範圍,若是與客戶端申請的範圍一致,此項可省略
    • state:若是客戶端的請求中包含這個參數,認證服務器的迴應也必須如出一轍包含這個參數

    有個須要注意的地方,步驟 C,返回的 access_token 放在重定向 URL 的 Fragment 中,即錨點中, # 後面,例如

    http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA &state=xyz&token_type=example&expires_in=3600

    由於錨點中的內容不會發送給後臺,從而減小了一次數據傳輸,下降了必定風險

    對於簡化模式得到的 access_token 有效期很短,通常是會話級的,即當會話結束時就失效

    密碼模式

    密碼模式中,用戶向客戶端提供本身的用戶名和密碼,客戶端使用這些信息,向"服務商提供商"索要受權。

    在這種模式中,用戶必須把本身的密碼給客戶端,可是客戶端不得儲存密碼(既然用戶信任你,你就必須兌現這個承諾)。

    密碼模式的特性決定,須要用在用戶對客戶端高度信任的狀況下,好比客戶端是操做系統的一部分,或者由一個著名公司出品,而認證服務器只有在其餘受權模式沒法執行的狀況下,才能考慮使用這種模式

    這裏只簡單介紹下,不作作詳細講解,若有興趣瞭解,能夠查閱文末參考

    客戶端模式

    客戶端模式指客戶端以本身的名義,而不是以用戶的名義,向"服務提供商"進行認證。嚴格地說,客戶端模式並不屬於 OAuth 框架所要解決的問題

    在這種模式中,用戶直接向客戶端註冊,客戶端以本身的名義要求"服務提供商"提供服務,其實不存在受權問題

    客戶端模式,就像二道販子(只爲借用比喻,並沒有貶義),將原始服務包裝後,再提供給最終用戶,常見於多租戶的 Saas 系統,例如統一提供支付通道、處理 GPS 信息等

    這裏也只簡單介紹下,若有興趣瞭解,能夠查閱文末參考

    刷新 access_token

    在 受權碼模式中,受權服務器能夠會同時返回 refresh_token,用來在 access_token 過時前,從新獲取新的access_token,不須要用戶從新確認受權,有助於提升用戶體驗

    在 access_token 過時前,客戶端可用 refresh_token 向受權服務器發送請求,例如,假設 b.com 是受權服務器地址,請求大致是:

    https://b.com/oauth/token? grant_type=refresh_token& client_id=CLIENT_ID& client_secret=CLIENT_SECRET& refresh_token=REFRESH_TOKEN
    • grant_type: 受權類型,值爲 'refresh_token'
    • client_id: 客戶端 id,即第三方應用在受權服務器上註冊被分配的 id
    • client_secret: 客戶端和受權服務器通行的密鑰,由受權服務器頒發,在特殊須要確認的狀況下須要做爲驗證條件
    • refresh_token: 用戶獲取新的 access_token 的 refresh_token

    安全的 OAuth2.0

    上面較爲詳細的講述了 OAuth2.0 框架,瞭解了在開放網絡中如何安全的獲取用戶受權的技術細節,但再完善的交互方案、再複雜的嚴密的通訊過程,都避免不了中間人攻擊,當客戶端和認證服務器之間經過 http 協議交互數據時,會被截取通訊內容,從而得到用戶的受權,這是不能接受的,因此 OAuth2.0 須要創建在 https 協議上,將通訊內容加密,最大程度的防止信息被竊取。

    若是 OAuth2.0 框架用在敏感信息交互上時,必須使用 https 協議確保安全,但並非說只能支持 https,對於非敏感數據,或者不重要的受權,可使用 http 協議做爲通訊方式

    總結

    本節課程着重介紹了 OAuth2.0 受權框架,從它的做用,到具體的技術細節,作了較爲詳細的講述,若是須要用安全的受權,須要將通訊創建在 https 協議之上。因爲 OAuth 概念較多,流程複雜,這節沒有涉及到具體的編程實踐,下一節,咱們以 Github 爲例,使用以前介紹過的 Authlib 模塊,用 Flash 實現一個第三方應用,做爲實踐,敬請期待

相關文章
相關標籤/搜索