Bearer Token (RFC 6750) 用於OAuth 2.0授權訪問資源,任何Bearer持有者都可以無差別地用它來訪問相關的資源,而無需證明持有加密key。一個Bearer代表授權范圍、有效期,以及其他授權事項;一個Bearer在存儲和傳輸過程中應當防止泄露,需實現Transport Layer Security (TLS);一個Bearer有效期不能過長,過期后可用Refresh Token申請更新。
一. 資源請求
Bearer實現資源請求有三種方式:Authorization Header、Form-Encoded Body Parameter、URI Query Parameter,這三種方式優先級依次遞減
- Authorization Header:該頭部定義與Basic方案類似
GET /resource HTTP/1.1 Host: server.example.com Authorization: Bearer mF_9.B5f-4.1JqM
- Form-Encoded Body Parameter: 下面是用法實例
POST /resource HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded access_token=mF_9.B5f-4.1JqM
使用該方法發送Bearer須滿足如下條件:
1.頭部必須包含"Content-Type: application/x-www-form-urlencoded" 2.entity-body必須遵循application/x-www-form-urlencoded編碼(RFC 6749) 3.如果entity-body除了access_token之外,還包含其他參數,須以"&"分隔開 4.entity-body只包含ASCII字符 5.要使用request-body已經定義的請求方法,不能使用GET
如果客戶端無法使用Authorization請求頭,才應該使用該方法發送Bearer
- URI Query Parameter:
GET /resource?access_token=mF_9.B5f-4.1JqM HTTP/1.1 Host: server.example.com
Cache-Control: no-store服務端應在響應中使用 Cache-Control: private
二. WWW-Authenticate頭
在客戶端未發送有效Bearer的情況下,即錯誤發生時,資源服務器須發送WWW-Authenticate頭,下為示例:
HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer realm="example", error="invalid_token", error_description="The access token expired"
下面將就WWW-Authenticate字段的用法進行詳細描述(下列這些屬性/指令不應重復使用):
- Bearer:Beare作為一種認證類型(基於OAuth 2.0),使用"Bearer"關鍵詞進行定義
- realm:與Basic、Digest一樣,Bearer也使用相同含義的域定義reaml
- scope:授權范圍,可選的,大小寫敏感的,空格分隔的列表(%x21 / %x23-5B / %x5D-7E),可以是授權服務器定義的任何值,不應展示給終端用戶。OAuth 2.0還規定客戶端發送scope請求參數以指定授權訪問范圍,而在實際授權范圍與客戶端請求授權范圍不一致時,授權服務器可發送scope響應參數以告知客戶端下發的token實際的授權范圍。下為兩個scope用法實例:
scope="openid profile email" scope="urn:example:channel=HBO&urn:example:rating=G,PG-13"
- error:描述訪問請求被拒絕的原因,字符%x20-21 / %x23-5B / %x5D-7E之內
- error_description:向開發者提供一個可讀的解釋,字符%x20-21 / %x23-5B / %x5D-7E之內
- error_uri:absolute URI,標識人工可讀解釋錯誤的頁面,字符%x21 / %x23-5B / %x5D-7E之內
當錯誤發生時,資源服務器將發送的HTTP Status Code(通常是400, 401, 403, 或405)及Error Code如下:
- invalid_request:請求丟失參數,或包含無效參數、值,參數重復,多種方法發送access token,畸形等。資源服務器將發送HTTP 400 (Bad Request)
- invalid_token:access token過期、廢除、畸形,或存在其他無效理由的情況。資源服務器將發送HTTP 401 (Unauthorized),而客戶端則需要申請一個新的access token,然后才能重新發送該資源請求
- insufficient_scope:客戶端提供的access token的享有的權限太低。資源服務器將發送HTTP 403 (Forbidden),同時WWW-Authenticate頭包含scope屬性,以指明需要的權限范圍
如果客戶端發送的資源請求缺乏任何認證信息(如缺少access token,或者使用 RFC 6750 所規定的三種資源請求方式之外的任何method),資源服務器不應該在響應中包含錯誤碼或者其他錯誤信息,如下即可:
HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer realm="example"
三. Bearer Token Response
下為示例:
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"mF_9.B5f-4.1JqM", "token_type":"Bearer", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA" }
四. 安全威脅
- Token 偽造/修改(Token manufacture/modification):攻擊者偽造或修改已有的token,導致資源服務器授權通過非法訪問的客戶端。因此需要對token使用數字簽名或消息認證碼來保證其完整性
- Token 泄露(Token disclosure):Token本身可能包含認證、有效期等敏感信息。因此實現TLS並驗證證書是必選項,加密token可用於防止客戶端觀察token的內容,加密token還可防止token在前端服務器和后端服務器(如果他們沒有啟用TLS)之間發生泄露
- Token 改寄(Token redirect):攻擊者用一個訪問A資源服務器的token去請求B資源服務器的資源。因此通常token中可以包含代表資源服務器的標識來防止這種情況的發生
- Token 重放(Token replay):攻擊者企圖使用曾經使用過的token來請求資源。因此token需包含有效期(比如少於1小時)
另外cookie不能包含token,關於cookie的安全弱點,RFC 6265 中有如下描述:
A server that uses cookies to authenticate users can suffer security vulnerabilities because some user agents let remote parties issue HTTP requests from the user agent (e.g., via HTTP redirects or HTML forms). When issuing those requests, user agents attach cookies even if the remote party does not know the contents of the cookies, potentially letting the remote party exercise authority at an unwary server.
可見即使服務端實現了TLS,攻擊者依舊可以利用cookie來獲取機密信息,如果cookie中包含機密信息的話;對此,不得已可將機密信息包含於URLs(前提是已實現了TLS),但盡量使用更安全的辦法,因為瀏覽器歷史記錄、服務器日志等可能泄露URLs機密信息。
五. Transport Layer Security (TLS)
TLS (SSL / TLS)源於NetScape設計的SSL(Secure Sockets Layer,1994 / SSL 1.0、1995 / SSL 2.0、1996 / SSL 3.0);1999年,IETF接替NetScape,發布了SSL的升級版TLS 1.0,最新為TLS 1.3(draft),TLS 用於在兩個通信應用程序之間提供保密性和數據完整性。目前,應用最廣泛的是TLS 1.0,接下來是SSL 3.0,主流瀏覽器都已經實現了TLS 1.2的支持。TLS 1.0通常被標示為SSL 3.1,TLS 1.1為SSL 3.2,TLS 1.2為SSL 3.3。獲取更多信息可參考 TLS 1.2 / RFC 5246 。
TLS是一種位於傳輸層(TCP)和應用層之間的協議層,由記錄協議(Record Layer)和握手協議(Handshake Layer)兩層構成:
TLS算法套件由三個部分組成:了解更多可參考 http://www.rfcreader.com/#rfc5246_line3649
- 密鑰交換算法: RSA或Diffie-Hellman算法的各種變種
- 加密算法: AES, DES, Triple-DES, RC4, RC2, IDEA 或 none
- 摘要算法: MD5, SHA
六. application/x-www-form-urlencoded Media Type
首先application/x-www-form-urlencoded這種編碼類型未考慮非US ASCII字符的情況,因此待編碼的內容(包括名稱、值)可先經UTF-8編碼,然后再按字節序列進行字符轉義操作;而接收這種數據類型則需進行逆向處理。通常各種web編程語言已經提供原生URL編碼/URL解碼接口(可能不同語言版本的URL編碼/解碼會有差異),使用起來也極為方便,因此這里不做詳細介紹。
七. MAC Token
MAC Token與Bearer Token一樣,可作為OAuth 2.0的一種Access Token類型,但Bearer Token才是RFC建議的標准;MAC Token是在MAC Access Authentication中被定義的,采用Message Authentication Code(MAC)算法來提供完整性校驗。
MAC Access Authentication 是一種HTTP認證方案,具體內容可參考: HTTP Authentication: MAC Access Authentication draft-hammer-oauth-v2-mac-token-05 。