簡單理解OAuth 2.0

我的博客地址:blog.sqdyy.cnhtml

OAuth2要解決的問題

開放系統間受權問題

OAuth2最初是基於開放系統間受權問題提出的,假設如今有一個第三方應用:「雲沖印服務」,能夠將用戶存儲在Google的照片沖印出來。用戶爲了使用該服務,必須讓「雲沖印服務」讀取本身儲存在Google上的照片。問題是隻有獲得用戶的受權,Google纔會贊成「雲沖印服務」讀取這些照片。那麼「雲沖印服務」如何獲取用戶的受權呢?前端

辦法1:密碼用戶名複製

辦法1密碼用戶名複製

傳統的辦法是,資源擁有者將本身的用戶名和密碼告訴第三方服務,而後第三方服務再去讀取用戶受保護的資源,這種作法適用於公司內部應用開發時使用,在開放系統間這麼作就不太合適了,由於第三方服務可能爲了後續的服務,會保存用戶的密碼,這樣很不安全。web

辦法2:萬能鑰匙

辦法2萬能鑰匙

另外一種方法是客戶應用和受保護的資源之間商定一個通用developer key,用戶在受保護資源方獲得一個developer key交給第三方應用,第三方應用再經過這個developer key去訪問用戶受保護的資源。這種方式適用客戶應用和受保護資源之間存在信任關係的狀況,如兩方是合做商,或是同個公司不一樣部門之間的應用。可是對於不受信的第三方應用來講這種方法也不合適。數據庫

辦法3:特殊令牌

辦法3特殊令牌

第三種方法是使用一個特殊令牌,它僅僅能訪問受保護的資源,這種作法相對前兩種方法要靠譜的多,而且和OAuth2的作法已經比較接近了,可是如何管理令牌,頒發令牌,吊銷令牌就須要一些講究了,這些咱們留到後面介紹OAuth2再來了解。後端

現代微服務安全問題

傳統單塊應用的架構中,一般咱們的單塊應用會部署到應用服務器作成集羣,其中會有一個專門用於處理登陸受權的用戶數據庫。當用戶訪問應用服務器時,會經過應用的攔截器進行攔截鑑權,若是鑑權登陸成功,一般由服務器發給客戶端一個會話標識Session ID,客戶端將Session ID存儲在Cookie中,服務器記錄Session ID與通過驗證的用戶的對應關係。瀏覽器

傳統單塊應用架構

相對而言,傳統單塊應用主要是直接面向PC用戶的Web應用,對於現代微服務架構而言,上面的作法就不適用了。對於現代微服務架構而言,服務之間拆分的粒度較小,須要考慮服務和服務之間的鑑權問題,另外就是應用的形態變得多種多樣,例若有單頁應用,無線原生APP,服務端APP。這種場景下咱們一般會設計一個獨立的服務,將認證和受權都作成一個AuthServer,經過Token的形式進行鑑權和受權,那麼這也是OAuth2解決的一個主要問題,咱們將在後面進行介紹。安全

現代微服務架構


OAuth的基本概念

OAuth2.0是用於REST/APIs的代理受權框架(delegated authorization framework),它基於令牌Token的受權,在無需暴露用戶密碼的狀況下,使應用能獲取對用戶數據的有限訪問權限。Oauth2.0能將認證和受權解耦,它是事實上的標準安全框架,支持多種應用場景,如服務端WebApp,瀏覽器單頁應用SPA,無線/原生App,服務器對服務器之間調用等等。服務器

OAuth2.0具備如下優點:session

  • 客戶端不接觸用戶密碼,服務端更易集中保護
  • 普遍傳播並被持續採用
  • 支持短壽命和封裝的Token
  • 資源服務器和受權服務器解耦
  • 集中式受權,簡化客戶端
  • HTTP/JSON友好,易於請求和傳遞Token
  • 考慮多種客戶端架構場景
  • 客戶端能夠具備不一樣的信任級別

OAuth2.0的不足:架構

  • 協議框架太寬泛,形成各類實現的兼容性和互操做性差
  • 和OAuth1.0不兼容

OAuth須要注意的地方:

  • OAuth並無支持HTTP之外的協議
  • OAuth並非一個認證協議
  • OAuth並無定義受權處理機制
  • OAuth並無定義Token類型
  • OAuth2.0並無定義加密方法
  • OAuth2.0並非單個協議。
  • OAuth2.0僅是受權框架,僅用於受權代理。

OAuth主要角色和術語

OAuth2主要角色

  • Client Application(客戶應用):一般是一個Web或者無線應用,它須要訪問用戶的受保護資源。
  • Resource Server(資源服務器):是一個Web站點或者Web service API,用戶的受保護數據保存在此。
  • Authorized Server(受權服務器):在客戶應用成功認證並得到受權以後,向客戶應用頒發訪問令牌Access Token。
  • Resource Owner(資源擁有者):資源的擁有人,想要分享某些資源給第三方應用。
  • Client Credentials(客戶憑證):客戶的clientId和密碼用於認證客戶。
  • Tokens(令牌):受權服務器在接收到用戶請求之後,頒發訪問令牌。
  • Scopes(做用域):客戶請求訪問令牌時。由資源擁有者額外指定細分權限(permission)

OAuth令牌類型

令牌Token是OAuth2.0的核心概念,令牌能夠類比爲一把僕從鑰匙(Valet Key),它給應用受權有限的訪問權限,讓應用可以表明用戶去訪問用戶的數據。

  • Authorization Code Token(受權碼):僅用於受權碼受權類型,用於交換獲取訪問令牌和刷新令牌。
  • Refresh Token(刷新令牌):用於去受權服務器獲取一個新的令牌。
  • Access Token(訪問令牌):用於表明一個用戶或服務直接去訪問受保護的資源。
  • Bearer Token:不論是誰拿到Token均可以訪問資源。
  • Proof of Possession(Pop) Token:能夠校驗client是否對Token有明確的擁有權。

OAuth2受權方式

先來看OAuth2.0的運行流程:

OAuth2.0的運行流程

  • (A)用戶打開客戶端之後,客戶端要求用戶給予受權。
  • (B)用戶贊成給予客戶端受權。
  • (C)客戶端使用上一步得到的受權,向認證服務器申請令牌。
  • (D)認證服務器對客戶端進行認證之後,確認無誤,贊成發放令牌。
  • (E)客戶端使用令牌,向資源服務器申請獲取資源。
  • (F)資源服務器確認令牌無誤,贊成向客戶端開放資源。

這裏的B步驟是關鍵,即客戶如何給客戶的受權,有了這個受權後客戶端就能夠獲取令牌,進而憑藉令牌獲取資源,OAuth2.0爲咱們提供了4種客戶端獲取受權的模式:

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

受權碼模式

受權碼模式相對其餘三個模式來講是功能最完整,流程最安全嚴謹的受權方式。它的特色是經過客戶端的後臺服務器與服務提供商的認證服務器進行交互:

受權碼模式

它的步驟以下:

  • (A)用戶訪問客戶端,客戶端將用戶導向認證服務器,須要攜帶客戶端ID憑證和重定向URI。
  • (B)用戶選擇是否給予客戶端受權。
  • (C)假設用戶給予受權,認證服務器將用戶導向事先指定的重定向URI,同時附上一個受權碼。
  • (D)客戶端收到受權碼後,在後臺服務器(對用戶不可見)攜帶事先指定的重定向URI和受權碼向認證服務器申請令牌。
  • (E)認證服務器覈對受權碼和重定向URI,確認無誤後,向客戶端頒發訪問令牌(access token)和刷新令牌(refresh token)。

簡化模式

簡化模式不經過服務端程序來完成,比受權碼模式減小了「受權碼」這個步驟,直接由瀏覽器發送請求獲取令牌,令牌對訪問者是可見的,且客戶端不須要認證,這種模式通常用於單頁應用:

簡化模式

它的步驟以下:

  • (A)用戶訪問客戶端,客戶端將用戶導向認證服務器,須要攜帶客戶端ID憑證和重定向URI。
  • (B)用戶選擇是否給予客戶端受權。
  • (C)假設用戶給予受權,認證服務器將用戶導向事先指定的重定向URI,並在URI的Hash部分包含了訪問令牌(Fragment)。
  • (D)瀏覽器向資源服務器發出請求,其中不包含事先收到的Hash部分(Fragment)。
  • (E)資源服務器返回一段腳本,其中包含的代碼能夠獲取Hash部分中的令牌。
  • (F)瀏覽器執行事先獲取的腳本,提取出令牌
  • (G)瀏覽器將令牌發送給客戶端。

密碼模式

密碼模式中,用戶向客戶端提供用戶名和密碼,客戶端使用這些信息,直接向認證服務器索要受權。這種模式違背了前面提到的微服務安全要解決的問題(不暴露用戶名和密碼),可是在一些用戶對客戶端高度信任的狀況下,例如公司內部軟件間的受權下,使用這種模式也是適用的:

密碼模式

它的步驟以下:

  • (A)用戶向客戶端提供用戶名和密碼。
  • (B)客戶端將用戶名和密碼發送給認證服務器,向認證服務器索要令牌。
  • (C)認證服務器確認無誤後,向客戶端提供訪問令牌。

客戶端模式

客戶端模式是客戶端以本身的名義去受權服務器申請受權令牌,並非徹底意義上的受權。主要應用於Docker到DokcerHub拉取鏡像的這類場景:

客戶端模式

它的步驟以下:

  • (A)客戶端向認證服務器進行身份認證,並要求獲取訪問令牌。
  • (B)認證服務器確認無誤後,向客戶端提供訪問令牌。

刷新令牌

若是用戶訪問的時候,客戶端的"訪問令牌"已通過期,則須要使用"更新令牌"申請一個新的訪問令牌:

刷新令牌

它的步驟以下:

  • (A)客戶端向認證服務器進行身份認證,並要求獲取訪問令牌。
  • (B)認證服務器確認無誤後,返回訪問令牌和一個刷新令牌。
  • (C)客戶端經過訪問令牌訪問受保護資源。
  • (D)若是訪問令牌未過時,則向客戶端提供資源服務。
  • (E)客戶端經過訪問令牌訪問受保護資源。
  • (F)若是訪問令牌過時,受保護資源服務器返回Invalid Token Error。
  • (G)客戶端獲得上方的錯誤後,經過刷新令牌向受權服務器申請一個新的訪問令牌。
  • (H)認證服務器確認無誤後,返回訪問令牌和一個刷新令牌。

OAuth2.0四種模式的選型

上面介紹了OAuth4種客戶端受權模式,下面介紹這4種模式的技術選型,在這以前先作兩個概念鋪墊:

受權流程渠道(channels): 前面提到了OAuth2的四個主要角色,這四個角色之間的交互能夠劃分紅兩類渠道,凡是資源擁有者、客戶應用和受權服務器之間的發送交互能夠劃分爲 前端渠道。凡是受權服務器、客戶應用和資源服務器之間發生的交互能夠劃分爲後端渠道

OAuth2主要角色

客戶應用類型:客戶應用也能夠劃分爲兩類應用,第一類是公開應用,主要是指單頁應用SPA或原生App應用,這類應用都是駐在用戶手中的,這種應用不能將用戶的憑證信息如密碼駐留在上面,通常只存用戶標識。第二類是私密應用,主要指Web服務端應用、服務/API(機器對機器間),這種應用是在後端運行的,總體上相對安全,能夠駐留用戶憑證信息。

四種OAuth2.0受權模式的特徵

在選型以前咱們先來彙總一下四種受權類型的特徵:

受權碼模式

  • 經過前端渠道客戶獲取受權碼
  • 經過後端渠道,客戶使用受權碼去交換訪問令牌和刷新令牌
  • 假定資源擁有者和客戶在不一樣設備上
  • 最安全的流程,由於令牌不會傳遞通過user-agent

簡化模式

  • 適用於公開的瀏覽器單頁應用
  • access token直接從受權服務器返回(只有前端渠道)
  • 不支持refresh token
  • 假定資源全部者和公開應用在同一個應用上
  • 最容易受到安全攻擊

用戶名密碼模式

  • 使用用戶名密碼登陸的應用,例如桌面App,內部軟件
  • 使用用戶名/密碼做爲受權方式從受權服務器上獲取access token
  • 通常不支持refresh token
  • 假定資源擁有者和公開用戶在相同設備上

客戶端模式

  • 適用於服務器間通訊廠家,機密客戶表明它本身或者一個用戶
  • 只有後端渠道,使用客戶憑證獲取一個access token
  • 由於客戶憑證可使用對稱或非對稱加密,該方式支持共享密碼或者證書

受權模式選型

綜合上述,在選型時能夠參考下面流程圖的思路:

受權模式選型

本文參考資料:

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息