https://tools.ietf.org/html/rfc6749 html
傳統的client-server受權模型,客戶端經過使用憑證(一般的用戶名和明文密碼)訪問服務端受保護的資源,爲了可以讓第三方應用程序訪問受保護的資源,須要將憑證共享給第三方。web
這就產生了一些問題和限制:算法
OAuth經過引入一個受權層,並分離客戶端和資源擁有者成不一樣的角色來解決這個問題。在OAuth中,經過發行不一樣的訪問令牌(包括資源訪問範圍、生命週期、其餘訪問屬性),而不是資源自己,來限制第三方應用程序訪問受保護資源(資源擁有者保護並宿主在資源服務器)的粒度和期限,而不是直接把憑證(用戶名和密碼)提供給客戶端。json
例如:一個終端用戶(資源擁有者)能夠受權一個打印服務(客戶端)來訪問宿主在圖片共享服務器(資源服務器)上的受保護的圖片(資源),而不用共享憑證(用戶名和密碼)給打印服務(客戶端)。瀏覽器
在OAuth中定義了4中角色:安全
資源全部者(resource owner)服務器
可以對受保護資源授予訪問權的實體,當資源的全部者是人時,指的就是咱們的終端用戶。 app
資源服務(resource server)框架
宿主受保護的資源。可以接受和響應使用訪問令牌(access tokens)對受保護資源的請求。分佈式
客戶端(client)
對受保護資源發起請求的應用程序。多是一個服務、桌面應用程序、或者其餘設備。
受權服務(authorization server)
成功認證資源全部者和得到受權後,發行訪問令牌給客戶端。
受權服務和資源服務之間的交互不在超過該規範,受權服務和資源服務多是同一個服務,也多是不一樣的服務。單個受權服務器應該能夠發行由多個資源服務器接受的訪問令牌。
+--------+ +---------------+ | |--(A)- Authorization Request ->| Resource | | | | Owner | | |<-(B)-- Authorization Grant ---| | | | +---------------+ | | | | +---------------+ | |--(C)-- Authorization Grant -->| Authorization | | Client | | Server | | |<-(D)----- Access Token -------| | | | +---------------+ | | | | +---------------+ | |--(E)----- Access Token ------>| Resource | | | | Server | | |<-(F)--- Protected Resource ---| | +--------+ +---------------+
(A) 客戶端向資源全部者請求受權,這時受權請求可能直接提交給資源全部者,也可能提交給受權服務(扮演一個受權終端)。
(B) 客戶端得到一個資源全部者受權許可的憑證。受權許可類型可使用規範中定義的4中類型,也能夠自定類型(注意:受權服務須要支持自定義受權許可類型)。
(C) 客戶端經過提交受權許可憑證給受權服務,請求訪問令牌。
(d) 受權服務認證客戶端並驗證受權許可憑證,頒發訪問令牌。
(E) 客戶端經過提交已認證的訪問令牌,請求受保護的資源。
(F) 資源服務驗證訪問令牌,若是有效,響應請求。
注意:客戶端獲取獲取受權許可憑證的首選方法,就是使用受權服務做爲一箇中介。
表明資源全部者受權的一個憑據,能夠用獲取訪問令牌;OAuth2.0 協議定義了4中受權許可類型:受權碼模式、隱性模式、資源全部者密碼憑證、客戶端憑證。也能夠自定義擴展的受權許可類型。
受權碼經過一個受權服務器得到,受權服務在客戶端和資源全部者之間扮演一箇中介。客戶端不是直接從資源全部者請求受權,而是將資源全部者指向受權服務器,而後受權服務器在將資源全部者引導到客戶端,並攜帶受權碼。在重定向資源服務器到客戶端以前,受權服務器認證資源全部者並得到受權。注意受權服務器僅僅認證資源全部者,並不會共享憑證給客戶端。
受權碼提供了一些重要的安全好處,例如認證客戶端,也能夠用於直接獲取令牌,而再也不須要通過資源全部者,也能夠暴露給其餘人,包括資源全部者。
隱性模式是受權碼模式的簡化版,使用一個腳本語言(例如:JavaScript)優化了客戶端的實現。在隱性模式中,資源全部者受權後,並不會爲客戶端頒發受權碼,而是直接頒發一個訪問令牌。由於並無頒發中間憑證(例如:受權碼),受權許可類型是隱性的,故稱之爲隱性模式。
在隱式受權流中發佈訪問令牌時,受權服務器不驗證客戶端。在某些狀況下,客戶端標識能夠經過傳遞訪問令牌給客戶端的重定向URI來識別,訪問令牌可以暴露給資源全部者和其餘資源全部者訪問的應用程序。隱性模式提升了某些客戶端的響應速度和效率(例如:做爲瀏覽器應用程序實現的客戶端),由於它減小了獲取訪問令牌所需的往返次數。可是當安全性要求很高的場景下,這種模式須要權衡,特別是當受權碼模式可用的狀況下。
客戶端的驗證受權(即用戶名和密碼)能夠直接做爲受權許可,來得到訪問令牌。只有當資源全部者充分信任(例如:客戶端是整個系統的一部分,或者是特權應用程序,或者其餘受權許可不可用時)客戶端的狀況下,才使用該模式。儘管這種受權許可類型要求客戶端直接訪問資源全部者的憑據,但資源全部者憑證只能用於單個請求,來交換訪問令牌。經過使用長壽命的訪問令牌或者刷新令牌,該模式消除了客戶端存儲資源全部者憑證(以備未來使用)的需求。
當受權範圍僅限於受客戶端控制的受保護資源時,客戶端憑據能夠用做受權許可。一般當客戶以本身的名義行事時(此時,客戶端也是一個資源全部者),客戶端許可會被使用。
訪問令牌是用於訪問受保護資源的憑證。訪問令牌是表示向客戶機頒發的受權的字符串,該字符串一般對客戶端不透明。該令牌帶有特定的範圍(控制資源訪問粒度)和持續時間,由資源全部者受權許可,資源服務器和受權服務器強行執行。令牌可能表示用於檢索受權信息的標識符,也可能以可驗證方式自包含受權信息(一個訪問令牌字符串由一些數據和一個簽名信息組成)。
訪問令牌是一個抽象的層,裏面放置着各類各樣資源服務器可以理解的構造信息(例如:資源的訪問範圍、持續時間等等)。經過抽象,也使訪問令牌的頒發不得到受權許可更受限制,同時也消除了資源服務器須要理解多種認證方法的須要。
基於資源服務器安全(例如:加密屬性)的需求,訪問令牌可能有不一樣的格式、結構、使用方法。
刷新令牌是一個用於獲取訪問令牌的憑證。刷新令牌由受權服務器頒發給客戶端,若是當前的訪問令牌無效或者過時時,獲取一個新的訪問令牌;或者強制再請求一個訪問令牌(可能相同或更窄範圍的訪問令牌)。與資源全部者相比,訪問令牌有更短的生命週期和更少的權限。對於受權服務器而言,頒發一個刷新令牌是可選的,可是當要頒發刷新令牌時,通常狀況下,刷新令牌是伴隨着訪問令牌一塊兒頒發的。
刷新令牌表明資源全部者對客戶端給予受權許可的字符串,經過對客戶端不透明。令牌表示用於檢索受權信息的標識符。與訪問令牌不一樣,刷新令牌僅用於受權服務器,且從不發送到資源服務器。
+--------+ +---------------+ | |--(A)------- Authorization Grant --------->| | | | | | | |<-(B)----------- Access Token -------------| | | | & Refresh Token | | | | | | | | +----------+ | | | |--(C)---- Access Token ---->| | | | | | | | | | | |<-(D)- Protected Resource --| Resource | | Authorization | | Client | | Server | | Server | | |--(E)---- Access Token ---->| | | | | | | | | | | |<-(F)- Invalid Token Error -| | | | | | +----------+ | | | | | | | |--(G)----------- Refresh Token ----------->| | | | | | | |<-(H)----------- Access Token -------------| | +--------+ & Optional Refresh Token +---------------+ 圖 2: 刷新一個過時的訪問令牌
(A) 客戶端請求受權服務器的認證,並提交受權許可。
(B) 受權服務器認證客戶端並驗證受權許可後,頒發訪問令牌和刷新令牌。
(C) 客戶端向資源服務器發出受保護的資源請求,並提交訪問令牌。
(D) 資源服務器驗證訪問令牌後,把受保護的資源響應給客戶端。
(E) 步驟(C)和(D)重複,直到訪問令牌過時。若是客戶端知道訪問令牌過時,就會跳到步驟(G)。不然,它將建立另外一個受保護的資源請求。
(F) 因爲訪問令牌無效,資源服務器返回一個無效的令牌錯誤。
(G) 客戶端請求一個新的訪問令牌,並提交刷新令牌。客戶端身份驗證需求基於客戶機類型和受權服務器策略。
(H) 受權服務器認證客戶端並驗證刷新令牌後,若是有效,頒發一個新的訪問令牌(此時,是否頒發一個新的刷新令牌是可選的)。
基於普遍部署和已知的安全漏洞,TLS版本都是隨着時間變化而變化的。TLS版本1是最普遍部署的版本,將提供最普遍的互操做性。具體實現還能夠支持知足其安全要求的附加傳輸層安全機制。
該規範充分利用了Http重定向,客戶端和受權服務器將資源全部者用戶代理重定向到另外的目的地。雖然規範中的示例顯示了HTTP 302狀態代碼的使用,可是容許用戶代理運用任何其餘方法來完成此重定向,並被認爲是實現細節。
OAuth 2提供了一個明確的安全特性豐富的受權框架。然而,做爲一個豐富且高度可擴展的框架,有許多可選組件,這一規範自己可能會產生普遍的非互操做性實現。此外,該規範還提供部分必需的部分或徹底未定義的組件(例如,客戶端註冊、受權服務器功能、端點發現)。沒有這些組件,針對一個特定的受權服務器,資源服務器的互操做,客戶端必須手動配置。這個框架的設計帶有明確的指望,將來的工做將定義實現完整Web規模互操做性所必需的規範配置文件和擴展。
該協議中的關鍵詞 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT","SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL"在 [RFC2119] 中被詳細的描述。該規範使用[RFC5234]中的 the Augmented Backus-Naur Form (ABNF)符號規範。此外,規則的URI引用被包含在「統一資源標識符(URI):通用語法」[ rfc3986 ]中。某些安全相關的術語被定義在[RFC4949]中,這些術語包括但不限於 "attack", "authentication", "authorization", "certificate","confidentiality", "credential", "encryption", "identity", "sign","signature", "trust", "validate", and "verify"。除非另有說明,全部協議參數名稱和值都是區分大小寫的。
在啓動協議以前,客戶端使用受權服務器進行註冊。客戶端經過受權服務器註冊的方式超過了該協議的範圍,可是通常都是終端用戶經過一個HTML表單提交註冊。客戶端註冊並不須要客戶端和受權服務器的直接交互,只要受權服務器支持,可使用各類各樣的放肆進行註冊並獲取已註冊客戶端的屬性。例如:可使用一個自發布或者第三方發佈的聲明(assertion)或者受權服務器經過一個信任的通道來進行客戶端的發現。
當註冊一個客戶端時,客戶端開發人員應該:
基於客戶端和受權服務器,安全認證的能力(例如:客戶憑證的保密性),OAuth定義了兩種類型的客戶端。
保密類型(confidential)
可以維護其憑證的保密性的客戶端(例如:客戶端在一個安全的服務器上,客戶端的訪問受到限制),可以經過其餘方式來保證客戶端認證的安全性。
公開類型(pulic)
不可以維護其憑證的保密性的客戶端(例如:在資源全部者的設備上執行客戶端,如已安裝的本機應用程序或基於Web瀏覽器的應用程序),不可以經過其餘方式來保證客戶端認證的安全性。
客戶機類型指定是基於受權服務器對安全認證的定義及其可接受的客戶端證書的暴露級別。受權服務器不該該對客戶端類型作出假設。客戶機能夠實現爲一組分佈式組件,每一個組件具備不一樣的客戶機類型和安全上下文(例如,一個分佈式客戶端既有基於服務器的機密組件,又有基於公共瀏覽器的組件);若是傳統受權服務器不可以對這樣的客戶端提供支持或者註冊引導,客戶應將每一個組件註冊爲單獨的客戶機。
本規範是圍繞如下客戶端配置文件設計的:
web 應用程序(web application)
Web應用程序是在Web服務器上運行的機密客戶端。資源全部者經過在其使用的設備上的經過用戶代理(瀏覽器)中呈現的HTML用戶界面訪問客戶端。客戶端憑據以及向客戶機發出的任何訪問令牌都存儲在Web服務器上,不會被資源全部者暴露或訪問。
基於用戶代理的應用程序(user-agent-based application)
基於用戶代理的應用程序是一個公共客戶端,其中客戶端代碼從Web服務器下載並在由資源全部者所使用的設備的用戶代理內執行。 因此,對於資源全部者,協議數據和憑證能夠很容易得到。因爲這些應用程序駐留在用戶代理中,因此在請求受權時能夠無縫地使用用戶代理功能。
本地應用程序(native application)
本機應用程序是安裝在資源全部者使用的設備上並執行的公共客戶機。對於資源全部者,協議數據和證書是可獲得的。假設能夠提取應用程序中包含的任何客戶端身份驗證憑據。另外一方面,動態發佈的憑據(如訪問令牌或刷新令牌)能夠收到可接受的保護級別。至少,這些憑據被保護免受應用程序可能交互的惡意服務器的保護。某些狀況下,這些應用程序也會受到保護免受駐留在同一設備的其餘應用程序的干擾。
受權服務器向註冊客戶端頒發客戶端標識符------表示客戶端提供的註冊信息的惟一字符串。客戶機標識符不是祕密,它暴露給資源全部者,不能單獨用於客戶端身份驗證。
客戶端標識符對受權服務器是惟一的。
客戶標識符字符串大小該規範未定義。客戶機應該避免對標識符大小作出假設。受權服務器應該記錄它所頒發的任何標識符的大小。
若是客戶機類型是機密的,客戶機和受權服務器創建適合於受權服務器的安全需求的客戶端身份驗證方法。受權服務器能夠接受知足其安全要求的任何形式的客戶端身份驗證。機密客戶機一般發佈(或創建)一組客戶端證書,用於與受權服務器進行身份驗證(例如,密碼、公鑰/私鑰對)。受權服務器能夠和公共客戶端創建客戶端認證方法。可是,受權服務器不能依賴公共客戶端身份驗證,以識別客戶機。在每一個請求中,客戶端不能使用多個身份驗證方法。
擁有客戶端密碼的客戶機可使用HTTP基自己份驗證方案和受權服務器進行身份驗證。客戶端標識使用"application/x-www-form-urlencoded"編碼算法進行編碼,編碼值用做用戶名。客戶端密碼使用相同的算法進行編碼,並用做密碼。受權服務器必須支持HTTP基自己份驗證方案,以驗證客戶端密碼並頒發密碼。
例如:受權 Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3,還有一種可選的方案就是,在請求頭中包含兩個參數(client_id和client_secret),這種方案通常不推薦,除非客戶端不可以使用 HTTP Basic authentication scheme (或者其餘的基於密碼的HTTP authentication scheme)。參數只能在請求體中傳輸,不能包含在請求URI中。
受權服務器能夠支持符合其安全要求的任何合適的HTTP認證方案。在使用其餘身份驗證方法時,受權服務器必須定義客戶端標識符(註冊記錄)和身份驗證方案之間的映射。
該規範沒有包含未註冊的客戶端的使用。這種客戶機的使用超出了本規範的範圍,須要對其互操做性影響進行額外的安全性分析和審查。
受權處理利用兩個受權服務器終結點:
客戶端經過用戶代理重定向到該端點得到資源全部者的受權。
客戶機用來交換訪問令牌的受權許可,一般具備客戶端身份驗證。
受權服務器用於經過資源全部者用戶代理將包含受權憑證的響應返回給客戶端。
並非每個受權許可類型都會使用這些終結點;固然擴展的受權許可類型能夠定義本身的終結點。
受權終結點與資源全部者交互獲取一個受權許可。首先受權服務器必須審覈資源全部者的身份信息(受權服務器採用什麼方式認證資源全部者的身份(例如:用戶名、密碼、會話Cookie),超出了本規範的訪問)。
受權URI可能包含 "application/x-www-form-urlencoded" 格式的必須的查詢組件(query parameters)。端點URI不能包含碎片組件(fragment component)。
因爲對受權端點的請求,致使用戶身份驗證和明文證書的傳輸。當發送請求到受權端點時,受權服務器必需要求使用TLS。受權服務器必須支持「Get」方法,也能夠支持「Post」方法。
發送請求時,沒有值的參數會被省略。受權服務器必須忽略沒法識別的請求參數。請求和響應參數不該包含超過一次。
受權終結點被受權碼模式和隱式模式使用。
客戶端經過下列參數來通知受權服務器指望創建的受權許可類型流:
response_type:必須。受權碼模式時,該值必須爲「code」。隱性模式時,該值必須爲「token」。還能夠爲咱們本身註冊的擴展值。若是一個受權請求確實該參數,或者受權服務器沒法理解該參數,將返回一個錯誤的響應。
在完成與資源全部者的交互以後,受權服務器將資源全部者的用戶代理引導回客戶端。重定向終結點URI必須爲完整的URI,端點的URI可能包括一個「application/x-www-form-urlencoded」格式的查詢組件,但不能包含「fragment 」組件。
當請求的響應類型爲「code」或「token」時,或者當咱們要傳送機密的憑證信息時,這個時候須要使用TLS。該規範並不強制使用TLS,由於在編寫此規範時,要求客戶機部署TLS是許多客戶機開發人員的一個重要障礙。若是TLS不可用,在重定向到受權服務器以前,應該警告資源全部者不安全端點的狀況。
傳輸層安全性的缺少會嚴重影響客戶端和受權訪問的受保護資源的安全性。當受權過程做爲客戶端委託的終端用戶身份驗證的一種形式時(例如:第三方登陸服務),傳輸層安全性的使用尤其重要。
受權服務器只接受下面的客戶端的註冊:
在使用受權服務器以前,應該要求全部的客戶端來註冊他們的完成受權後的重定向端點。客戶機可使用「state」請求參數來實現每一個請求定製。若是要求徹底重定向URI的註冊是不可能的,受權服務器應該要求URI scheme, authority, and path的註冊(容許客戶端動態的改變重定向URI的查詢組)。受權服務器也容許客戶端註冊多個重定向端點。缺乏重定向URI註冊要求,增長攻擊者利用受權端點的風險。
若是多個重定向URI已註冊,或者只有重定向URI的一部分已被註冊,或者重定向URL沒有被註冊,則在客戶端的受權請求的查詢組件中,必須包含"redirect_uri"參數。當一個重定向的URI被包含在受權請求中時,受權服務器必須跟以註冊的客戶端重定向URI做比較和匹配,若是沒有就跟客戶端自己的URL做比較。
若是因爲受權請求參數缺失,無效,或者不能匹配無效的URI,受權服務器應該告知一個錯誤給資源全部者。
返回給客戶端的請求一般是一個HTML文檔。若是HTML響應做爲重定向請求的結果直接送達,則HTML文檔中包含的任何腳本都將執行對重定向URI及其所包含的憑據的徹底訪問。在重定向端點的響應中,客戶端不該該包含任何第三方的腳本,相反它應該提取出憑證,而後重定向用戶代理到另外的不會暴露憑證信息的端點。若是,包含第三方腳本,客戶端必須保證首先執行本身的腳本。
令牌端點被客戶端用來獲取訪問令牌(經過呈現一個包含受權信息的受權許可)或者刷新令牌。除了隱式受權類型(訪問令牌是直接頒發的。)外,其餘的三種受權許可類型都會使用令牌端點。
客戶端獲取令牌端點地址的方法超過了本規範的範疇,可是一般都是在一個服務文檔中提供。
由於對令牌端點的請求會涉及到憑證的明文傳輸,全部要求必須使用TLS,而且必須使用Post方法。
當向令牌端點發起請求時,爲機密客戶端和其餘的客戶端頒發的客戶端憑證必須和受權服務器進行受權。
當發送請求的令牌端點時,客戶可使用「client_id」請求參數標識自己。在經過「authorization_code」和「grant_type」對令牌端點發起請求時,未經身份驗證的客戶端必須發送「client_id」以防止本身無心間接受一個來自於其餘客戶端「client_id」的代碼。這樣也防止客戶端的受權碼被替換,可是這並不對受保護的資源提供額外的安全性保障。
經過在請求中添加參數"scope",受權端點和令牌端點容許客戶端指定請求所訪問的範圍。一樣的,受權服務器也是用「scope」響應參數來表示頒發給客戶端的訪問令牌的範圍。「scope」參數的值表示爲空格分隔的、區分大小寫的字符串的列表。該字符串由受權服務器定義。
基於受權服務器的策略和資源全部者的指示,受權服務器可能會徹底或者部分忽略客戶端請求的「scope」參數。若是已發佈的訪問令牌範圍與客戶端請求的範圍不一樣,受權服務器必須包含「scope」響應參數,告知客戶端實際範圍授予。
若是客戶端在請求受權時省略了範圍參數,則受權服務器必須使用預先定義的範圍默認值處理請求,或者失敗指示無效範圍的請求。受權服務器應該記錄它的範圍要求和默認值。
爲了得到一個訪問令牌,客戶端須要向資源全部者得到受權,受權以許可(authorization grant)的形式被呈現。OAuth定義了4中許可類型:authorization code(受權碼), implicit(隱性),resource owner password credentials(資源全部者密碼憑證), and client credentials(客戶端憑證)。它也提供了擴展的機制來定義額外的受權許可類型。
受權碼許可類型能夠用於獲取訪問令牌和刷新令牌,它是爲機密客戶端憑證優化的。因爲這是一個基於重定向的流程,客戶端必須可以與資源全部者的用戶代理(一般是一個webbrowser)進行交互,並可以接收來自於受權服務器的傳入請求(重定向)。
+----------+ | Resource | | Owner | | | +----------+ ^ | (B) +----|-----+ Client Identifier +---------------+ | -+----(A)-- & Redirection URI ---->| | | User- | | Authorization | | Agent -+----(B)-- User authenticates --->| Server | | | | | | -+----(C)-- Authorization Code ---<| | +-|----|---+ +---------------+ | | ^ v (A) (C) | | | | | | ^ v | | +---------+ | | | |>---(D)-- Authorization Code ---------' | | Client | & Redirection URI | | | | | |<---(E)----- Access Token -------------------' +---------+ (w/ Optional Refresh Token)
注意:經過上圖能夠看到,到客戶端通過用戶代理時,(A)、(B)、(C)被分紅了兩步。
圖3:受權碼流程
(A)客戶端經過重定向資源全部者的用戶代理重定向到受權服務器(注意資源服務與受權服務不是同一臺服務器),並在請求中包含客戶端標識符、請求的範圍、本地狀態、重定向URI等參數,一旦受權服務器許可或者拒絕後,就會返回到用戶代理。
(B)受權服務器認證資源全部者(經過用戶代理),肯定資源全部者的許可,或者拒絕客戶端的訪問請求。
(C)假如資源全部者許可訪問,根據早前在客戶端認證階段提供的重定向URI,並攜帶參數受權碼和本地狀態(早前在客戶端認證階段提供的),重定向用戶代理到客戶端。
(D)經過在請求中包含受權碼和重定向URI,客戶端從令牌端點獲取訪問令牌。
(E)受權服務器驗證受權碼和重定向URI(和客戶端認證階段提供的重定向URI進行匹配),若是有效,攜帶訪問令牌和刷新令牌(可選)響應返回。
經過添加下列參數到查詢組件(query component)中(注意使用 "application/x-www-form-urlencoded" ),發起對受權端點URI的請求。
response_type(請求類型):必須,值必須爲「code」
client_id(客戶端身份標識):必須
redirect_uri(重定向URI):可選
scope(請求的範圍):可選
state(客戶端本地狀態):必須,客戶機用來維護請求和回調之間的狀態的不透明值。當將用戶代理重定向回客戶端時,受權服務器包含此值。該參數應用於防止跨站點請求僞造。
經過Http重定向響應或者其餘用戶代理可以接受的方式,客戶端將資源全部者導向已構建好的URI。例如,客戶端指導用戶代理來發起下面的Http請求:
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com
受權服務器驗證請求來保證全部必須的參數都存在和有效。若是請求有效,受權服務器經過認證資源全部者來得到受權決定。若是受權決定被許可,受權服務器就會重定向用戶代理到客戶端提供的重定向URI。
若是資源全部者許可訪問請求,受權服務頒發一個受權碼,並以"application/x-www-form-urlencoded"格式添加下列參數到重定向URI查詢組件(query)中。
code:必須。由受權服務器生成的受權碼。受權碼被頒發後,必須短暫過時,下降泄露風險,最長的生命週期推薦10分鐘,客戶端只能使用一次受權碼;若是被第二次使用時,受權服務器必須註銷頒發給該受權碼的全部令牌。
state:狀態。若是該參數在以前的客戶端受權請求中被包含,則返回時必須原封不動的帶上此參數。
例如:受權服務器經過發送下面的Http 響應重定向用戶代理到客戶端。
HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
客戶端必須忽略不能識別的響應參數,受權碼字符串的長度本規範並未定義。客戶端應該避免對受權碼長度的猜想,受權服務器應該記錄下所頒發的受權碼的長度。
若是因爲缺失、無效、不匹配重定向URI和客戶端標識符,受權服務器應該通知資源全部者錯誤,不能自動的重定向用戶代理到無效的重定向URI。
若是資源全部者拒絕客戶端的訪問請求,受權碼服務器應該使用"application/x-www-form-urlencoded"格式添加下列參數到重定向URI的查詢組件(query component)中。
error:必須。一個簡單的、來自於包含下面參數的 ASCII 錯誤代碼。
invalid_request(無效請求):請求缺乏所需的參數,包括無效的參數值,其中包含一次以上的參數,或者是其餘格式錯誤的。
unauthorized_client(未受權的客戶端):客戶端沒有受權使用此方法請求受權碼。
access_denied(訪問拒絕):資源全部者或者受權服務器拒絕請求。
unsupported_response_type(不支持的響應類型):受權服務器不支持使用此方法得到受權代碼。
invalid_scope(無效的請求範圍):請求的範圍無效、未知或格式錯誤。
server_error(服務器錯誤):受權服務器遇到意外狀況,阻止它執行請求(由於當重定向時,一個500內部錯誤Http狀態碼不能返回給客戶端,因此這個錯誤碼是必須的。)。
temporarily_unavailable(暫時不可用):因爲臨時服務器超載或維護,受權服務器目前沒法處理請求。
error_description(錯誤的描述):可選。提供額外信息,人類可讀的ASCII碼文本字符串。幫助客戶端的開發者理解發生的錯誤。
error_uri(錯誤URI):可選。帶有錯誤信息的且可讀的Web頁面,用於向客戶端開發人員提供關於錯誤的附加信息。
state(狀態):可選。若是在客戶機受權請求中存在「state」參數,則須要原封不動的返回。
例如:受權服務器經過發送下面的Http 響應重定向用戶代理到客戶端。
HTTP/1.1 302 Found
Location: https://client.example.com/cb?error=access_denied&state=xyz
客戶端對令牌端點發送請求,並添加下列參數到查詢組件(query component)中(注意使用 "application/x-www-form-urlencoded" ),在在HTTP請求實體中使用utf-8字符編碼。
grant_type(受權許可類型):必須。值必須爲「authorization_code」
code(受權碼):必須。從認證服務器請求的受權碼。
redirect_uri(重定向URI):必須。若是重定向URI被包含在受權請求中,則值必須與客戶端認證階段包含的重定向URI相同。
client_id(客戶端身份標識):必須。若是客戶端不使用受權服務器進行身份驗證。若是客戶端類型是機密的,或者客戶端已經被頒發的憑證,或者被分配其餘的受權要求,則客戶端必須使用受權服務器進行身份驗證。
例如,客戶端使用TLS發送如下HTTP請求:
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
受權服務器必須:
若是訪問令牌請求有效並已被受權,則受權服務需頒發一個必須的訪問令牌和一個可選的刷新令牌。若是請求客戶端認證失敗或者無效,受權服務器將返回錯誤的響應。
成功響應的例子:
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }
隱式許可類型用於獲取訪問令牌(不支持發行刷新令牌),而且它對運行特定重定向URI的公共客戶機進行了優化。 這些客戶機一般使用JavaScript等腳本語言實現,並運行在客戶端中。因爲這是一個基於重定向的流程,客戶端必須可以與資源全部者的用戶代理(一般一個web瀏覽器)進行交互,而且可以接受來自於受權服務傳入(經過重定向)的請求。
不像受權碼許可類型,客戶端分別請求受權和訪問令牌,而是直接接收訪問令牌做爲受權請求的結果。 隱式受權類型不包括客戶端身份驗證,依賴於資源全部者的存在和重定向URI的註冊。由於訪問令牌被編碼到重定向URI中,因此它可能暴露在資源全部者和駐留在同一設備上的其餘應用程序中。
+----------+ | Resource | | Owner | | | +----------+ ^ | (B) +----|-----+ Client Identifier +---------------+ | -+----(A)-- & Redirection URI --->| | | User- | | Authorization | | Agent -|----(B)-- User authenticates -->| Server | | | | | | |<---(C)--- Redirection URI ----<| | | | with Access Token +---------------+ | | in Fragment | | +---------------+ | |----(D)--- Redirection URI ---->| Web-Hosted | | | without Fragment | Client | | | | Resource | | (F) |<---(E)------- Script ---------<| | | | +---------------+ +-|--------+ | | (A) (G) Access Token | | ^ v +---------+ | | | Client | | | +---------+
圖4:隱性許可流程
(A)客戶端將資源服務器的用戶代理導向受權端點,幷包含客戶端標識、請求範圍、本地狀態、重定向URI等參數,一旦訪問被許可,受權服務器將返回到用戶代理。
(B)受權服務器認證資源全部者,並肯定資源全部者是許可仍是拒絕客戶端的訪問請求。
(C)假如資源全部者許可訪問,根據早前在客戶端認證階段提供的重定向URI,並在URI片斷(fragment)中包含訪問令牌,重定向用戶代理到客戶端。
(D)用戶代理保留本地UIR片斷,向客戶端Web託管資源服務器發起請求。
(E)客戶端Web託管資源服務器返回一個web頁面,幷包含可以在URI片斷中的提取訪問令牌(和其餘參數)的腳本。
(F)用戶代理執行腳本,提取訪問令牌(和其餘參數)
(G)用戶代理將訪問令牌傳送給客戶端。
經過添加下列參數到查詢組件(query component)中(注意使用 "application/x-www-form-urlencoded" ),發起對受權端點URI的請求。
response_type(響應類型):必須。值必須爲「Token」。
client_id(客戶端標識):必須。
redirect_uri(重定向URI):可選。
scope(請求的範圍):可選。
state(客戶端本地狀態):推薦。客戶機用來維護請求和回調之間的狀態的不透明值。當將用戶代理重定向回客戶端時,受權服務器包含此值。該參數應用於防止跨站點請求僞造。
經過Http重定向,客戶端將資源全部者導向使用上面參數構造的受權服務器URI請求。例如,客戶端指導用戶代理使用TLS來發起下面的Http請求:
GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 Host: server.example.com
受權服務器驗證請求來保證全部必須的參數都存在和有效。受權服務器必須(由於須要它來攜帶訪問令牌)驗證重定向URI,並與以前客戶端認證提供的重定向URI進行匹配。若是請求有效,受權服務器經過認證資源全部者來得到受權決定(或者經過其餘標準來得到受權許可)。若是受權決定被許可,受權服務器就會重定向用戶代理到客戶端提供的重定向URI。
若是資源全部者許可訪問請求,受權服務器就會頒發一個訪問令牌,並以"application/x-www-form-urlencoded"格式添加下列參數到重定向URI片斷組件(query fragment)中。
access_token(訪問令牌):必須。
token_type(令牌類型):必須。
expires_in(過時時間):推薦。訪問令牌的生命週期,值「3600」表示訪問令牌將在一個小時後過時。若是省略,受權服務器,應該設置一個默認值,或者經過其餘的方式提供過時時間。
scope(範圍):可選。若是等同於客戶端請求的範圍則可選,不然必須。
state(狀態):可選。若是在客戶機受權請求中存在「state」參數,則必須原封不動的返回。
受權服務器不能頒發刷新令牌
例如:受權服務器經過發送下面的Http 響應重定向用戶代理。
HTTP/1.1 302 Found Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA &state=xyz&token_type=example&expires_in=3600
開發人員應該注意到一些用戶代理不支持在HTTP「location」響應頭字段中包含一個片斷組件。這樣的客戶端會要求使用其餘方法重定向客戶端,而不是一個3xx重定向響應。例如,返回一個HTML頁面,其中包含一個與重定向URI連接的動做的「繼續」按鈕。
客戶端必須忽略不能識別的響應參數,受權碼字符串的長度本規範並未定義。客戶端應該避免對受權碼長度的猜想,受權服務器應該記錄下所頒發的受權碼的長度。
若是因爲缺失、無效、不匹配重定向URI和客戶端標識符,受權服務器應該通知資源全部者錯誤,不能自動的重定向用戶代理到無效的重定向URI。
若是資源全部者拒絕客戶端的訪問請求,受權碼服務器應該使用"application/x-www-form-urlencoded"格式添加下列參數到重定向URI的查詢組件(query component)中。
error:必須。一個簡單的、來自於包含下面參數的 ASCII 錯誤代碼。
invalid_request(無效請求):請求缺乏所需的參數,包括無效的參數值,其中包含一次以上的參數,或者是其餘格式錯誤的。
unauthorized_client(未受權的客戶端):客戶端沒有受權使用此方法請求受權碼。
access_denied(訪問拒絕):資源全部者或者受權服務器拒絕請求。
unsupported_response_type(不支持的響應類型):受權服務器不支持使用此方法得到受權代碼。
invalid_scope(無效的請求範圍):請求的範圍無效、未知或格式錯誤。
server_error(服務器錯誤):受權服務器遇到意外狀況,阻止它執行請求(由於當重定向時,一個500內部錯誤Http狀態碼不能返回給客戶端,因此這個錯誤碼是必須的。)。
temporarily_unavailable(暫時不可用):因爲臨時服務器超載或維護,受權服務器目前沒法處理請求。
error_description(錯誤的描述):可選。提供額外信息,人類可讀的ASCII碼文本字符串。幫助客戶端的開發者理解發生的錯誤。
error_uri(錯誤URI):可選。帶有錯誤信息的且可讀的Web頁面,用於向客戶端開發人員提供關於錯誤的附加信息。
state(狀態):可選。若是在客戶機受權請求中存在「state」參數,則須要原封不動的返回。
例如:受權服務器經過發送下面的Http 響應重定向用戶代理到客戶端。
HTTP/1.1 302 Found Location: https://client.example.com/cb#error=access_denied&state=xyz
只有當資源全部者充分信任(例如:客戶端是整個系統的一部分,或者是特權應用程序,或者其餘受權許可不可用時)客戶端的狀況下,才使用該模式。當使用該模式時,受權服務器應該特別當心,而且只有在其餘受權流不可用的狀況下,才使用該模式。
此受權類型適用於可以得到資源全部者證書的客戶端(用戶名和密碼,一般使用交互式表單)。它還用於遷移現有客戶使用直接的認證方案,如HTTP基本或摘要經過將存儲的憑據來訪問令牌的OAuth認證。
+----------+ | Resource | | Owner | | | +----------+ v | Resource Owner (A) Password Credentials | v +---------+ +---------------+ | |>--(B)---- Resource Owner ------->| | | | Password Credentials | Authorization | | Client | | Server | | |<--(C)---- Access Token ---------<| | | | (w/ Optional Refresh Token) | | +---------+ +---------------+
圖5:資源全部者密碼憑證流程
(A)資源全部者向客戶端提供用戶名和密碼。
(B)客戶端經過包含從資源全部者收到的憑據,請求來自受權服務器令牌端點的訪問令牌。當發起請求時,客戶端與受權服務器進行認證。
(C)受權服務器認證客戶端,並驗證資源全部者憑證,若是有效,頒發一個訪問令牌。
客戶機獲取資源全部者證書的方法超出了本規範的範圍。一旦訪問令牌得到,客戶端必須丟棄憑據(理想狀態)。
客戶端對令牌端點發送請求,並添加下列參數到查詢組件(query component)中(注意使用 "application/x-www-form-urlencoded" ),在在HTTP請求實體中使用utf-8字符編碼。
grant_type(受權許可類型):必須。值必須爲「password」 。
username(用戶名):必須 。
password(密碼):必須。
scope(請求的範圍):可選
例如:客戶端使用TLS發送下面的請求=>
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded
grant_type=password&username=johndoe&password=A3ddj3w
受權服務器必須:
因爲此訪問令牌請求使用資源全部者的密碼,受權服務器必須保護端點不受暴力攻擊(例如使用速度限制、驗證碼、彈窗等等)。
若是訪問令牌請求有效並已被受權,則受權服務需頒發一個必須的訪問令牌和一個可選的刷新令牌。若是請求客戶端認證失敗或者無效,受權服務器將返回錯誤的響應。
成功響應的例子:
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }
當客戶端僅僅想使用本身的憑證請求訪問受其控制的,或請求受權服務器已經配置的另外一個資源全部者的受保護資源。
客戶憑證許可類型必須僅由機密客端使用。
+---------+ +---------------+ | | | | | |>--(A)- Client Authentication --->| Authorization | | Client | | Server | | |<--(B)---- Access Token ---------<| | | | | | +---------+ +---------------+ 圖 6: 客戶端憑證流程
(A)客戶端和受權服務器進行認證,並向令牌端點請求訪問令牌。
(B)受權服務器認證客戶端,若是,有效,則頒發訪問令牌。
由於客戶端憑證被做爲受權許可,全部不須要其餘額外的受權請求。
客戶端對令牌端點發送請求,並添加下列參數(注意使用 "application/x-www-form-urlencoded" 格式和utf-8字符編碼)在HTTP請求實體中。。
grant_type(受權許可類型):必須。值必須爲「client_credentials」 。
scope(請求的範圍):可選
例如:客戶端使用TLS發送下面的請求=>
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=client_credentials
受權服務器必須認證客戶端。
若是訪問令牌請求有效並已被受權,則受權服務需頒發一個必須的訪問令牌和一個可選的刷新令牌。若是請求客戶端認證失敗或者無效,受權服務器將返回錯誤的響應。
成功響應的例子:
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "example_parameter":"example_value" }
經過與受權服務器進行溝通,客戶端將受權服務器定義好的受權許可類型的值做爲參數「grant_type」的值,也能夠包含其餘的一些參數,向令牌端點發送請求。