OAuth--Open standard for Authorization

 

       OAUTH

1. 什麼是OAuth ?

官網這樣說...php

An open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications.web

  • OAuth 即 Open standard for Authorization
  • OAuth就是一個網絡開放協議。爲保證用戶資源的安全受權提供了簡易的標準
  • 在知乎上看到了一個比較直觀的比喻,有助於初學者理解。知乎話題連接

2. OAuth 歷史版本

  • 2007-12 OAuth 1.0發佈並迅速成爲工業標準。
  • 2008-06 OAuth 1.0 Revision A發佈,這是個稍做修改的修訂版本,主要修正一個安全方面的漏洞。
  • 2010-04,OAuth 1.0 協議發佈爲 RFC 5849
  • 2011-05 OAuth 2.0 草案發布
  • 2012-10 OAuth 2.0 協議發佈爲 RFC 6749

3. OAuth 1.0

OAuth 1.0 協議過於複雜,易用性差,因此並無獲得普及,下文中給出了受權的流程圖,能夠簡單瞭解瞭解,如今不多有用的了。瀏覽器

OAuth Authentication Flow

OAuth Authentication Flow安全

關於OAuth 1.0, 想了解的能夠看看這些:服務器

4. OAuth 2.0

OAuth 2.0是目前的最新版本,OAuth 2.0不兼容OAuth 1.0。這篇文章主要講講OAuth 2.0,並以此展開。網絡

先來講一個場景:好比你第一次打開簡書官網,想要註冊一個帳號。你會看到簡書容許你經過新浪微博帳號登錄。當你點擊以後,須要你登錄微博。以後會出現「是否贊成簡書獲取你的我的信息」等等,若是你選擇受權,以後會跳轉回簡書。你會發現你在簡書的用戶名就是你微博的用戶名。而後,你會發出一條新的微博好比「我加入了簡書,一個基於內容分享的社區!」(這只是舉個例子,不知道簡書有沒有這樣作)。app

好了,這回開始進入正題ide

4.1 角色(roles)

OAuth 2.0 定義了四個角色網站

  • 資源擁有者(Resource Owner)
    資源擁有者其實就是用戶(user),用戶將會受權一個第三方應用能夠獲取他們的帳戶資源。固然第三方應用程序對於用戶帳戶的操做是有限制的(好比,read access, read and write access)!這個限制就是用戶受權時給予的權限範圍(scope)
    上面場景中,微博帳戶就是資源擁有者。read access就好比讀取微博用戶名,write access就好比以你的名義發了一個微博。spa

  • 客戶端(Client)
    客戶端就是前面說的第三方應用程序,他們想要獲取用戶的帳戶資源,但在這麼作以前必須通過受權
    上面場景中,簡書就是客戶端

  • 資源服務器(Resource Server)
    資源服務器存放用戶帳戶以及帳戶信息和資源
    上面場景中,新浪微博就是資源服務器,同時也是受權服務器

  • 受權服務器(Authorization Server)
    受權服務器驗證用戶身份,併爲第三方應用程序頒發受權令牌(access token)

資源服務器與受權服務器能夠是同一臺服務器,這裏分開主要是便於解釋清楚OAuth協議。從程序開發者的角度,這兩個都是service's API會執行的事情。

在瞭解完OAuth中的四個角色以後,咱們看看這四個角色之間是如何互動的。下面是基本運行流程。

Abstract Protocol Flow

Abstract Protocol Flow

  1. 應用程序向用戶請求給予受權,以便獲取服務器資源
  2. 若是用戶贊成受權,應用程序將得到相應受權
  3. 應用程序向受權服務器提供本身的身份證實(app key和app secret)和已被受權的證實(authorization grant),並請求訪問令牌(access token)
  4. 若是應用程序的身份被覈實,而且受權是有效地,那麼受權服務器將會發放訪問令牌給應用程序。此時,受權完成
  5. 應用程序向資源服務器出示訪問令牌,並請求資源
  6. 若是訪問令牌是有效的(好比:是否僞造,是否越權,是否過時),資源服務器將會爲應用程序提供資源

4.2 應用程序註冊(Application Registration)

對於一個應用程序來講,若是它想要使用OAuth,那麼首先它要在服務提供商那裏註冊。通常出如今網站的「developer」或者「API」部分。

應用程序要提供:

  • 應用程序名稱(Application Name)
  • 應用程序網站(Application Website)
  • 回調URL(Redirect URI or Callback URL)

在用戶贊成受權(或者拒絕)以後,服務提供商會將用戶從新導向這個Callback URL,這個Callback URL要來負責處理受權碼或者訪問令牌。

應用程序註冊完成以後,服務提供商會頒發給應用程序一個「客戶端認證信息(client credentials)」。Client Credential包括:

  • Client Identifier(client ID/API key/consumer key)
    • 提供給服務提供商,用於識別(identify)應用程序
    • 用於構建提供給用戶請求受權的URLs
  • Client Secret(secret key/API secret/consumer secret)
    • 提供給服務提供商,用於驗證(authenticate)應用程序
    • 只有應用程序和服務提供商二者可知

4.3 受權許可類型(Authorization grant types)

OAuth 2.0 定義了四種受權模式:

  • 受權碼模式(Authorization Code)
    used with server-side Applications
  • 隱式受權模式(Implicit)
    used with Mobile Apps or Web Applications (applications that run on the user's device)
  • 資源擁有者密碼憑證模式(Resource Owner Password Credentials)
    used with trusted Applications, such as those owned by the service itself
  • 客戶端模式(Client Credentials)
    used with Applications API access

4.4 受權碼模式(Authorization Code)

  • 受權碼模式是最多見的一種受權模式,最爲安全和完善。
  • 對於服務器端應用程序(server-side application)來講,能夠保證Client Secret的安全性。應用程序必須可以和用戶代理(user agent)進行交互,獲取API受權碼。

Authorization Code Flow

Authorization Code Flow

第一步:客戶端把用戶代理定向到受權終端(Authorizaiton Endpoint)

https://www.example.com/v1/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read
  • www.example.com/v1/oauth/authorize: API受權的終端(Authorization Endpoint)
  • client_id: 應用程序的client ID,用於API識別應用程序
  • redirect_uri:得到受權碼以後,服務提供商重定向用戶代理(好比瀏覽器)的地址
  • response_type:代表受權類型,默認值是code,即受權碼模式(Authorization Code Grant)
  • scope: 即應用程序能夠得到的受權級別(access level),默認值爲read
  • state: 表示客戶端的當前狀態,能夠指定任意值,認證服務器會原封不動地返回這個值,用於抵制CSRF攻擊。

第二步:用戶受權應用程序

用戶點擊上述URI以後,用戶首先要登錄,證實其身份。而後選擇贊成受權應用程序能夠訪問他們的帳戶或者拒絕。

是否容許簡書訪問你的微博帳戶

是否容許簡書訪問你的微博帳戶

第三步:應用程序獲取受權碼

若是用戶贊成受權,服務提供商會將用戶代理重定向到第一步中的redirect_uri,而且會包含受權碼

https://www.jianshu.com/callback?code=AUTHORIZATION_CODE

第四步:應用程序請求受權令牌

應用程序向API token終端發送剛剛得到的受權碼,以及認證信息。

https://www.example.com/v1/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL

URI中包括:

  • www.example.com/v1/oauth/token: API token的終端
  • client_id:即app key/consumer key,用於驗證應用程序
  • client_secret: 即app secret/consumer secret,用於驗證應用程序
  • grant_type:剛剛得到的受權碼
  • redirect_uri: 重定向URI,與第一步一致

第五步:應用程序得到受權令牌

若是上一步驗證有效,API將返回一個HTTP回覆。

{"access_token":"ACCESS_TOKEN","token_type":"bearer","expires_in":2592000,"refresh_token":"REFRESH_TOKEN","scope":"read"}

HTTP回覆中包含:

  • access_token:訪問令牌
  • token_type:令牌類型,bearer類型或mac類型。詳細
  • expires_in:過時時間,單位爲秒。
  • refresh_token:更新令牌,用來獲取下一次的訪問令牌,可選項。
  • scope:權限範圍,若是與客戶端申請的範圍一致,此項可省略。

4.5 隱式受權模式(Implicit)

  • 隱式受權模式主要用於客戶端應用程序(client-side application),好比手機應用、桌面客戶端應用程序和運行於瀏覽器上的web應用程序。
  • 由於沒有server端,client secret的保密性不能獲得保證。受權令牌給予用戶代理(好比,瀏覽器),再由用戶代理交給應用程序。因此用戶設備上的其餘應用程序一樣能夠獲得受權令牌。
  • 隱式受權模式中,應用程序不須要認證。
  • 隱式受權模式不支持refresh token。

Implicit Flow

Implicit Flow

第一步:客戶端把用戶代理定向到受權終端(Authorizaiton Endpoint)

  • 受權終端是https://www.example.com/authorize
  • 與受權碼連接相似,只不過response_type=token而不是code
https://www.example.com/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read

第二步:用戶受權應用程序

用戶點擊上述URI以後,用戶首先要登錄,證實其身份。而後選擇贊成受權應用程序可訪問他們的帳戶或者拒絕

是否容許簡書訪問你的微博帳戶

是否容許簡書訪問你的微博帳戶

第三步:用戶代理收到受權令牌

假設用戶贊成受權,受權服務器重定向用戶代理到第一步提到的redirect_uri。並在URI fragment中包含受權令牌(但不能查看)。

https://www.example.com/callback#token=ACCESS_TOKEN

第四步:用戶代理向資源服務器發出請求

用戶代理依照重定向的指令,向資源服務器發出請求,但並不包含上一步中獲得的受權令牌(#後面的部分)。用戶代理將完整的重定向URI保存在本地。

第五步:資源服務器返回一個網頁

資源服務器會返回一個網頁(一般是一個HTML文件內嵌一段腳本)。這段內嵌的腳本(script)能夠訪問第三步中用戶代理保存在本地的完整的重定向URI,並從中提取受權令牌。

第六步:用戶代理提取受權令牌

用戶代理執行上面提到的腳本,提取出受權令牌。而後將受權令牌傳遞給應用程序。

4.6 資源擁有者密碼憑證模式(Resource Owner Password Credentials)

  • 在資源擁有者密碼憑證模式中,用戶直接嚮應用程序提供其認證信息(即用戶名和密碼)。應用程序依此向受權服務器獲取受權令牌。
  • 這種模式適用於用戶對應用程序高度信任的狀況。好比是用戶操做系統的一部分。
  • 認證服務器只有在其餘受權模式沒法執行的狀況下,才能考慮使用這種模式。

Password Credentials Flow

Password Credentials Flow

第一步:用戶傳遞認證信息

用戶將用戶名和密碼交給應用程序。

第二步:應用程序請求受權令牌

  • 應用程序獲得用戶認證信息後,向受權服務器請求受權令牌。
  • 請求受權令牌終端https://www.example.com/token
  • response_type=password,前面提到的兩種分別是codetoken
https://www.example.com/token?grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID

第三步:受權服務器返回受權令牌

若是用戶的認證信息獲得驗證,受權服務器將嚮應用程序返回受權令牌。

4.7 客戶端模式(Client Credentials)

  • 客戶端模式應用於應用程序想要以本身的名義與受權服務器以及資源服務器進行互動。
  • 好比應用程序想要修改自身註冊信息或者redirect URI。又或者想要獲取資源服務器中不與具體用戶相關的信息。好比一個應用程序想要獲取新浪微博中含有#happy的微博。
  • 嚴格意義上說,客戶端模式並非OAuth協議要解決的問題,由於並未涉及受權。

Client Credentials Flow

Client Credentials Flow

第一步:應用程序請求受權令牌

  • 應用程序向受權服務器提供自身認證信息(client ID和client secret),並請求受權令牌。
  • 請求受權令牌終端https://www.example.com/token
  • response_type=client_credentials,前面提到的兩種分別是codetokenpassword
https://www.example.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET

第二步:受權服務器返回受權令牌

受權服務器驗證認證信息,嚮應用程序返回受權令牌。

4.7 更新令牌(Refresh Token)

  • 若是受權令牌過時,在進行API請求時會報錯Invalid Token Error
  • 若是在獲取受權令牌時,同時得到了refresh token,那麼咱們能夠向受權服務器申請更新令牌。
  • grant_type = refresh_token
  • scope:表示申請的受權範圍,不能夠超出上一次申請的範圍,若是省略該參數,則表示與上一次一致。
    https://www.example.com/v1/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN

                              原文:http://www.jianshu.com/p/b06944c92228

相關文章
相關標籤/搜索