OAuth 2.0 教程

分類:IT技術 時間:2016-10-17

OAuth 2.0

(原文:http://tutorials.jenkov.com/oauth2/index.html)

OAuth 2.0 教程

OAuth 2.0 是一個開放的標準協議,允許應用程序訪問其它應用的用戶授權的數據。例如:一個遊戲可以獲取Facebook中的用戶信息,或者是一個地理位置程序可以獲取Foursquare的用戶信息等。
這兒是一個示例圖:
Alt text
首先用戶進入遊戲的web應用,該應用要求用戶通過Facebook賬戶登錄,並定向到Facebook的登錄界面,用戶登錄Facebook後,會重定向到之前的遊戲應用。此時該應用就獲取到了用戶在Facebook的用戶數據以及授權信息。

OAuth 2.0 用例

OAuth 2.0既可以用於在某個應用內訪問其它應用的用戶信息,又可以提供用戶授權服務供其它應用調用。
OAuth 2.0是OAuth 1.0的替代,因為OAuth 1.0太復雜了,比如OAuth 1.0要求使用證書等。OAuth 2.0更加簡單,不要求使用證書,僅使用SSL/TLS。

OAuth 2.0 規範

這個教程的目的是提供一個OAuth 2.0協議的概覽以幫助理解,而不是涵蓋此協議的所有細節。
如果你計劃實現一個OAuth 2.0協議,最好是去閱讀規範的詳細內容,規範的地址:http://tools.ietf.org/html/draft-ietf-oauth-v2-23

OAuth 2.0 概述

在之前的介紹中我們提到,OAuth 2.0是一個開放標準,其允許應用程序訪問其它應用的用戶授權的數據。現在我們來介紹這個協議是如何工作的,以及規範中提到的各種概念。
OAuth 2.0 提供了不同的方式去獲取權限用語訪問資源服務器中的資源。現在介紹其中最安全和最常用的使用方式:一個web應用如何請求訪問另一個web應用的訪問權限。
下面的示例圖描述了整個處理過程:
Alt text
首先用戶訪問客戶端應用,在這個應用中會有一個“通過Facebook登錄”的按鈕。
第二步,當用戶點擊這個按鈕時,用戶被重定向到認證服務器(Facebook)。然後用戶開始登錄,登錄成功後會被詢問客戶端應用是否可以使用他的用戶信息。用戶點擊確認按鈕。
第三步,認證服務器將用戶重定向到客戶端應用提供的URL。這個重定向URL一般會在認證服務器中進行註冊,註冊是由客戶端應用的所有者進行的。註冊完成後,認證服務器會生成一個client id和client password。重定向後的URL會有一個code參數,該參數是此次認證的一個標識。
第四步,重定向完成後,用戶會進入重定向後的頁面,同時客戶端應用會在後臺與認證服務器進行通訊,發送client id,client password和上一步獲取到的code參數到認證服務器,認證服務器返回access token給客戶端應用。
一旦客戶端應用拿到了access token,就可以用這個token去訪問Facebook提供的相關資源。

OAuth 2.0 應用角色

OAuth 2.0定義了以下應用角色:

Resource Owner (資源所有者)
Resource Server (資源服務器)
Client Application (客戶端應用)
Authorization Server (認證服務器)

Alt text
Resrouce Owner(資源所有者)是數據的所有者。例如:Facebook或Google上的一個用戶就是一個Resrouce Owner。他們所擁有的資源就是用戶數據。示例圖中的那個用戶的圖標代表的就是Resrouce Owner。Resrouce Owner也可以是一個應用程序。

Resource Server(資源服務器)是存放資源的服務,例如Facebook或Google就是Resource Server。

Client Application(客戶端應用)會請求訪問存放在資源服務器上的資源,這些資源是屬於Resource Owner(資源所有者)的。

Authorization Server(認證服務器)對Client Application(客戶端應用)進行授權,授權通過後客戶端應用才可以訪問資源服務器上的資源。認證服務器和資源服務器可以是同一個應用,也可以分開獨立部署。

OAuth 2.0 客戶端類型

OAuth 2.0規範定義了2種客戶端類型:

  • 私密型
  • 公開型

私密型客戶端會保存client password。認證服務器會給每一個客戶端應用生成一個client password,認證服務器通過該client password來識別該客戶端應用是一個註冊過的應用,而不是其它的欺詐程序。一個web應用可以是私密性客戶端,只有系統管理員可以登錄這個應用的服務器和查看client password。

公開型客戶端不會保存client password。例如移動APP或桌面程序,如果client password被保存在此類應用中,就可以通過破解手段拿到client password,這是非常不安全的。

客戶端應用表現形式

  • Web Application (web應用)
  • User Agent (富web客戶端)
  • Native (原生應用)

Web Application(web應用)

web程序運行在web服務器上。web應用做認證時用到的client password是保存在服務器上的,因此是私密的。下面是一個web應用的示例圖:

Alt text

User Agent Application(富web客戶端)

富web客戶端應用是指由Javascript構建的web應用,瀏覽器是客戶端代理。這類應用的特點是,程序是存放在web服務器上的,但是運行時,瀏覽器下載javascript程序到本地,直接在瀏覽器中執行,例如那些用javascript開發的網頁版遊戲。下面是一個富web客戶端的示例圖:

Alt text

Native(原生應用)

(註:這裏指沒有後端服務器的應用,一次所有的數據和配置只能存放在客戶端程序中)
原生應用包括移動APP和桌面程序。原生應用直接安裝在用戶的設備上(電腦或手機、平板),client password會保存在用戶的設備裏。下面是一個原生應用的示例圖:
Alt text

Hybrid(混合應用)

這類應用通常是將原生應用和web應用的開發技術混合在一起,也會有對應的後端服務器。OAuth 2.0規範中並沒有提及此類應用,此類應用可以靈活選用上述三種認證類型中的任何一種。

OAuth 2.0 認證

  • Client ID, Client Secret and Redirect URI
  • Authorization Grant
  • Authorization Code
  • Implicit
  • Resource Owner Password Credentials
  • Client Credentials

當一個客戶端應用要訪問資源服務器上的資源時,需要先獲取到認證授權。

Client ID, Client Secret and Redirect URI

客戶端應用需要在認證服務器上註冊,註冊完成後,認證服務器會生成這個應用的client id和client password。client_id和client_password在同一個認證服務器中是唯一的,不會重復。客戶端應用可以在多個認證服務器中進行註冊(如分別在Facebook和Google中註冊),不同的認證服務器會為客戶端應用生成不同的client_id和client_password。
當客戶端應用需要訪問資源服務器上的資源時,首選要通過認證服務器進行認證,認證時要發送對應的client_id和client_password到認證服務器。
客戶端應用在認證服務器進行註冊時,需要填寫一個重定向URL。當資源所有者對客戶端應用進行授權成功後,資源所有者(可簡單理解為系統用戶)會被重定向到重定向URL所指定的頁面。

認證授權

資源所有者會給客戶端應用認證授權,認證授權時需要認證服務器和資源服務器進行配合。

OAuth 2.0規範列舉了4中認證授權方式,每種方式都有不同的安全特點:

  • Authorization Code(授權碼模式)
  • Implicit(簡化模式)
  • Resource Owner Password Credentials(用戶密碼模式)
  • Client Credentials

下面來對每一種授權方式進行解釋。

Authorization Code(授權碼模式)

Authorization Code(授權碼)的認證過程如下:

  1. 資源所有者(用戶)進入客戶端應用。
  2. 客戶端應用讓用戶通過認證服務器進行登錄。
  3. 登錄之前,客戶端應用會把用戶重定向到認證服務器的登錄頁面,同時把client id發送到認證服務器,這樣認證服務器就知道是哪一個客戶端應用在請求認證授權。
  4. 用戶在認證服務器上進行登錄,登錄成功後,會提示用戶是否要對客戶端應用進行授權,用戶選擇同意後,會被重定向回客戶端應用。
  5. 當重定向回客戶端應用時,使用的是客戶端應用在認證服務器上註冊時填寫的重定向URL,同時認證服務器會發送一個代表此次認證過程的一個授權碼。
  6. 當成功重定向到客戶端應用後,客戶端應用會在後臺與認證服務器進行交互,將上個步驟中獲取到的授權碼,連同client id,client password發送給認證服務器。
  7. 認證服務器對收到的數據進行校驗,通過後發送access token給客戶端應用。
  8. 這時客戶端應用就可以用接收到的access token去資源服務器訪問相關資源。下面是一個示例圖:

Alt text

Implicit(簡化模式)

Implicit(簡化模式)與Authorization Code(授權碼模式)類似,區別僅在於當用戶成功登錄之後,重定向到客戶端應用時,access token會直接返回給客戶端應用。
這意味著access token在客戶端應用中是可見的。而Authorization Code(授權碼模式),access token是在web服務器中的,對客戶端來說不可見。這是這兩種模式的最大區別。
並且,客戶端應用只發送client id到認證服務器。如果連同client password一起發送的話,client password需要存儲在客戶端應用中,這會是一個安全隱患,很容易通過破解手段拿到存放在客戶端應用程序中的client password。下面是一個示例圖:

Alt text

Resource Owner Password Credentials(用戶密碼模式)

Resource Owner Password Credentials(密碼模式)允許客戶端應用直接使用用戶的用戶名和密碼。例如用戶可以直接在客戶端應用中錄入Twitter的用戶名和密碼。
只有在充分信任客戶端應用的情況下,才能使用密碼模式。(因為用戶名和密碼是在客戶端應用中錄入的,因此客戶端應用可以獲取並保存用戶的用戶名和密碼)。
密碼模式一般在富web客戶端應用和原生應用中使用。

Client Credentials(客戶端模式)

Client Credentials模式用於訪問跟用戶無關的資源,因此不需要用戶授權。

OAuth 2.0 節點

OAuth 2.0定義了節點集合。一個節點一般是web服務器上的一個URL。具體包括:

  • 認證節點
  • Token節點
  • 重定向節點

認證節點和Token節點在認證服務器上,重定向節點在客戶端應用上。示例圖如下:

Alt text

OAuth 2.0規範並沒有對節點的URL做出明確的定義,不同的實現會提供不同的URL。

認證節點

認證節點是用戶進行登錄操作的地址。

Token節點

Token節點是認證服務器提供的,讓客戶端應用獲取access token的地址。

重定向節點

重定向節點在客戶端應用中,用戶成功登錄後,會被重定向到此地址。

OAuth 2.0 請求和響應

當客戶端應用請求access token時,會發送http請求到認證服務器。不同的認證授權類型會有不同的請求和響應內容。認證授權類型有4種:

  • Authorization Code(授權碼模式)
  • Implicit(簡化模式)
  • Resource Owner Password Credentials(用戶密碼模式)
  • Client Credentials

每種類型的請求和響應內容會在後續的內容中詳細解釋。

OAuth 2.0 Authorization Code(授權碼模式)的請求和響應

授權碼模式有2個請求和2個響應:

  • 認證請求+響應
  • access token請求+響應。

授權請求

授權請求發送到認證服務器,然後會獲取到一個授權碼。

response_type   必選項,固定值為 "code"
client_id   必選項, 客戶端應用在認證服務器註冊時生成的client id.
redirect_uri    可選項. T客戶端應用在認證服務器註冊時填寫的重定向URL地址.
scope   可選項. 請求的權限範圍.
state   可選項 (建議提供). 客戶端應用的請求URL中的參數,可以是任意值.

授權響應

授權響應含有授權碼,這個授權碼在後續獲取access token時需要提供。

code    必選項. 認證服務器返回的授權碼.
state   必選項, 如果客戶端應用的請求中有這個參數,既為這個參數的值.

授權錯誤響應

授權錯誤的情形有2種。

第一種是客戶端應用驗證失敗,例如授權請求中發送的重定向URL與客戶端應用在認證服務器中註冊時填寫的URL不一致。

第二種是產生了其它錯誤,此時下面的錯誤信息會返回給客戶端應用:

error   Required. Must be one of a set of predefined error codes. See the specification for the codes and their meaning.
error_description   Optional. A human-readable UTF-8 encoded text describing the error. Intended for a developer, not an end user.
error_uri   Optional. A URI pointing to a human-readable web page with information about the error.
state   Required, if present in authorization request. The same value as sent in the state parameter in the request.

Token請求

客戶端應用獲取到授權碼後,可以用此授權碼去獲取access token。請求參數如下:

client_id   Required. The client application's id.
client_secret   Required. The client application's client secret .
grant_type  Required. Must be set to authorization_code .
code    Required. The authorization code received by the authorization server.
redirect_uri    Required, if the request URI was included in the authorization request. Must be identical then.

Token 響應

access token的響應內容是json格式的:

{ "access_token"  : "...",
  "token_type"    : "...",
  "expires_in"    : "...",
  "refresh_token" : "...",
}

access_token : 訪問令牌,
token_type : 令牌類型,一般是bearer,
expires_in : 以秒為單位的令牌失效時間,
refresh_token : 當訪問令牌失效時,可以用更新令牌獲取一個新的訪問令牌

OAuth 2.0 簡化模式的請求和響應

簡化模式只有一個請求和一個響應。

簡化模式授權請求

該請求的參數如下:

response_type   Required. Must be set to token .
client_id   Required. The client identifier as assigned by the authorization server, when the client was registered.
redirect_uri    Optional. The redirect URI registered by the client.
scope   Optional. The possible scope of the request.
state   Optional (recommended). Any client state that needs to be passed on to the client request URI.

簡化模式授權響應

響應包含以下參數,註意該響應的格式不是json的。

access_token    Required. The access token assigned by the authorization server.
token_type  Required. The type of the token
expires_in  Recommended. A number of seconds after which the access token expires.
scope   Optional. The scope of the access token.
state   Required, if present in the autorization request. Must be same value as state parameter in request.

簡化模式錯誤響應

有2種情況會導致錯誤:
第一種是客戶端應用驗證失敗,例如授權請求中發送的重定向URL與客戶端應用在認證服務器中註冊時填寫的URL不一致。

第二種是產生了其它錯誤,此時下面的錯誤信息會返回給客戶端應用:

error   Required. Must be one of a set of predefined error codes. See the specification for the codes and their meaning.
error_description   Optional. A human-readable UTF-8 encoded text describing the error. Intended for a developer, not an end user.
error_uri   Optional. A URI pointing to a human-readable web page with information about the error.
state   Required, if present in authorization request. The same value as sent in the state parameter in the request.

用戶密碼模式的請求和響應

用戶密碼模式只有一個請求和響應。

用戶密碼模式的請求

請求包含以下參數:

grant_type  必選項. 固定值 "password"
username    必選項. UTF-8編碼的用戶名.
password    必選項. UTF-8編碼的密碼.
scope   可選項. 請求的權限範圍.

用戶密碼模式的響應

響應的內容是json格式:

{ "access_token"  : "...",
  "token_type"    : "...",
  "expires_in"    : "...",
  "refresh_token" : "...",
}

access_token : 訪問令牌,
token_type : 令牌類型,
expires_in : 以秒為單位的令牌失效時間,
refresh_token : 當訪問令牌失效時,可以用更新令牌獲取一個新的訪問令牌

客戶端模式的請求和響應

客戶端模式的請求

請求包含以下參數:

grant_type  必選項. 固定值 "client_credentials". 
scope   可選項. 請求的權限範圍.

客戶端模式的響應

響應包含以下參數:

{ "access_token"  : "...",
  "token_type"    : "...",
  "expires_in"    : "...",
}

access_token : 訪問令牌,
token_type : 令牌類型,
expires_in : 以秒為單位的令牌失效時間,
註意,此種授權類型沒有refresh_token


Tags: Foursquare Facebook 用戶登錄 應用程序 服務器

文章來源:


ads
ads

相關文章
ads

相關文章

ad