1. 程式人生 > >OpenID Connect Core 1.0(四)使用授權碼流驗證(上)

OpenID Connect Core 1.0(四)使用授權碼流驗證(上)

3.1 使用授權碼流驗證(Authentication using the Authorization Code Flow)

本節描述如何使用授權碼流執行驗證。當使用授權碼流時,會從令牌終結點返回的所有令牌。

授權碼流返回授權碼給客戶端,這個授權碼可以直接交換一個ID Token和一個Access Token。這給User Agent提供了不暴露任何令牌的好處,因為可能還有其他惡意的應用程式訪問User Agent。授權伺服器也可以在驗證客戶端之前通過Access Token交換的授權碼。授權碼流適合那些可以安全地在客戶與金鑰授權伺服器之間進行客戶密碼維護的場景。

3.1.1 授權碼流步驟(Authorization Code Flow Steps)

授權碼流經過以下步驟。

1、客戶準備一個包含所需的驗證請求的請求引數。

2、客戶端傳送請求到授權伺服器。

3、授權伺服器驗證使用者。

4、授權伺服器獲得使用者同意/授權。

5、授權伺服器給終端使用者傳送回一個授權碼給客戶端。

6、客戶端使用授權碼向令牌終結點請求一個響應。

7、客戶端接收到包含一個ID Token和Access Token響應body。

8、客戶端驗證ID Token和檢索終端使用者的 Subject識別符號。

3.1.2 授權終結點(Authorization Endpoint)

授權終結點對終端使用者的驗證。是通過傳送User Agent到授權伺服器的驗證和授權的終結點,其請求引數在OAuth 2.0中定義,額外的引數和引數值定義在OpenID Connect中定義。

授權終結點的通訊必須使用TLS。參看16.17節中關於TLS的更多資訊。

3.1.2.1驗證請求(Authentication Request)

一個驗證請求是OAuth 2.0由授權伺服器的終端使用者驗證的授權請求。

授權伺服器必須支援使用授權終結點在RFC 2616中定義的HTTP GET和POST方法。客戶可以使用HTTP GET或POST方法來發送授權請求到授權伺服器。如果使用HTTP GET方法,請求引數的序列化是使用每URI查詢字串序列化(13.1節)。如果使用HTTP POST 方法,請求引數序列化使用表單序列化形式(13.2節)。

OpenID Connect使用下面的OAuth 2.0授權碼流的請求引數:

scope

必需的。OpenID Connect請求必須包含 openid scope值。如果 openid scope值不存在,其行為是完全不確定的。可能存在其他scope值。對不能理解 scope實現值應該被忽略。參看(5.4 和 11 這個規範定義的額外的scope值部份)。

response_type

必需的。決定授權處理的流程,並從終結點返回什麼樣的引數是由OAuth 2.0響應型別值所決定。當使用授權碼流,其值是 code。

client_id

必需的。OAuth 2.0 對授權伺服器有效的客戶端識別符號。

redirect_uri

必需的。將由響應傳送的重定向URL。此URI必須是精確匹配客戶端預先註冊的OpenID提供者的重定向URI值,匹配執行的描述在 6.2.1節 (RFC3986) (簡單的字串比較)。當使用此流程,重定向URI應該使用 https 方案; 但它也可以使用 http方案,在這種OP允許使用 http 重定向URL提供方式情況下,如何提供客戶端型別保密,在OAuth 2.0 2.1節中定義。重定向的URI可能使用一個替代方案,比如,例如,當目的是識別本機應用程式一個回撥時。

state

推薦。不透明值,在維護請求和回撥之間狀態時使用。一般來說,是通過瀏覽器一個cookie加密值,以降低跨站請求偽造(CSRF XSRF)。

OpenID Connect也使用OAuth 2.0請求引數,此定義在 OAuth 2.0有多個響應型別編碼實踐。

response_mode

可選的。通知授權伺服器從授權終結點返回引數使用的機制。不推薦使用這個響應模式引數,而將其請求設定為響應型別指定的預設模式。

此規範還定義了以下請求引數:

nonce

可選的。字串值,用於關聯客戶端會話的ID Token,以減輕重播攻擊。該值在驗證ID Token請求中不會修改。Nonce必須有足夠的複雜度去防止攻擊者猜測值。實現說明,請參閱 15.5.2節 。

display

可選的。驗證和授權伺服器的ASCII字串值,指示如何顯示在經由終端使用者同意的使用者介面頁面上,定義的值是:

page

授權伺服器應該顯示的驗證和同意UI與一個完整的User Agent頁面一致的檢視。如果沒有指定顯示引數,就採用預設顯示模式。

popup

授權伺服器應該顯示驗證和一致的使用者同意介面的一個彈出User Agent視窗。彈出User Agent視窗應該適當的大小,在整個視窗中不應掩蓋login-focused對話方塊呈現。

touch

授權伺服器應該在利用可觸控裝置中顯示的驗證和一致的使用者同意介面。

wap

授權伺服器應該在“功能手機”中顯示的驗證和一致的使用者同意介面。

授權伺服器也可能試圖檢測User Agent功能,並呈現一個適當的顯示。

prompt

可選的。空格分隔的,區分大小寫的ASCII字串值列表,指定是否授權伺服器提示終端使用者重認證和同意。定義的值是:

none

授權伺服器不能顯示任何驗證或同意的使用者頁面。如果一個終端使用者還沒有經過驗證或客戶端沒有預配置請求同意宣告或不滿足其他條件處理請求時返回一個錯誤。通常的錯誤程式碼是login_required ,interaction_required ,或定義在 3.1.2.6節的另外的程式碼 。可以用於檢查現有的授權 和/或 同意的方法。

login

授權伺服器應該提示終端使用者重認證。如果終端使用者不能重認證,必須返回一個錯誤,通常 login_required 。

consent

授權伺服器應該提示終端使用者准許,然後返回資訊到客戶端。如果不能獲得准許,它必須返回一個錯誤,通常 consent_required 。

select_account

授權伺服器應該提示使用者選擇一個帳戶。這在一個終端使用者有多個賬戶的授權伺服器上在當前會話中進行多個帳戶選擇。如果不能獲得一個由終端使用者選擇的帳戶,必須返回一個錯誤,通常 account_selection_required 。

提示引數能被客戶端使用,以確保終端使用者在當前會話中存在或者請求意圖。如果這個引數不包含任何其他值,則返回錯誤。

max_age

可選的。驗證最大過期時間。指定允許存續時間,以秒為單位,是自上次通過OP終端使用者啟用驗證的存續時間,如果存續時間大於這個值,OP必須積極嘗試對終端使用者進行重新確認。(max_age 請求引數對應 OpenID 2.0 PAPE (OpenID.PAPE)的 max_auth_age 請求引數)。當使用max_age,返回的ID Token中必須包括一個 auth_time 宣告值。

ui_locales

可選的。終端使用者介面的首選語言和指令碼,表示為一個BCP47 RFC5646語言標記值的空格分隔的列表,按偏好排序。如,值“fr-CA fr en”代表了一種偏好:加拿大的法語、法語(沒有指定一個區域),其次是英語(沒有指定一個區域)。如果OpenID提供者不支援部分和所有請求的區域設定不應該產生錯誤

id_token_hint

可選的。之前由授權伺服器簽發的ID Token,作為暗示,傳遞給終端使用者與客戶驗證的當前或過去會話。如果終端使用者已經被登入的ID Token登確認或已登入的請求,那麼授權伺服器返回一個肯定的響應; 否則,它應該返回一個錯誤,如 login_required 。在可能的情況下,當 prompt=none 時應該使用id_token_hint,如不是則應返回一個 invalid_request 錯誤;當然,伺服器應該在允許的情況下響應成功,即使它不存在。授權伺服器不應當在ID Token使用id_token_hint值時坐視不理。

如果RP接收到被OP加密的ID Token,並使用它作為id_token_hint ,客戶端必須解密簽名ID Token中包含加密ID Token。客戶可能使用認證伺服器能解密的鍵值重加密簽名ID Token,和用重新加密ID Token方式加密id_token_hint值。

login_hint

可選的。關於終端使用者可能使用登入識別符號登入(如果有必要)提示給授權伺服器。這種暗示可以被RP使用,如果它首先尋問終端使用者的電子郵件地址(或其他識別符號),然後想通過這個值作為一個發現授權服務提示。建議提示值匹配用於發現的值。這個值可能是一個電話號碼的格式指定 phone_number 宣告。由OP決定是否使用這個引數。

acr_values

可選的。請求的驗證上下文類引用值。指定了被請求處理驗證請求授權伺服器使用的 acr空格分隔的字串值,值的出現按優先順序排列。作為 acr 宣告值返回滿足執行驗證的驗證上下文類,第二節指定,acr 宣告請求是主動宣告的引數。

其他引數可能會被髮送。部分參看 3.2.2 ,3.3.2 ,5.2 ,5.5 ,6 ,7.2.1 ,由該規範定義的額外的授權請求引數和引數值。

下面是一個非規範的例子,由客戶機的 HTTP 302重定向響應,User Agent驗證請求授權終結點觸發器:

  HTTP/1.1 302 Found

  Location: https://server.example.com/authorize?

    response_type=code

    &scope=openid%20profile%20email

    &client_id=s6BhdRkqt3

    &state=af0ifjsldkj

    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb

下面是請求非規範化的例子,這將是由User Agent傳送到授權伺服器,響應的HTTP 302重定向響應客戶端上面:

  GET /authorize?

    response_type=code

    &scope=openid%20profile%20email

    &client_id=s6BhdRkqt3

    &state=af0ifjsldkj

    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1

  Host: server.example.com

3.1.2.2驗證請求驗證(Authentication Request Validation)

授權伺服器必須驗證收到的請求如下:

1、授權伺服器必須根據OAuth 2.0規範驗證所有的 OAuth 2.0引數。

2、驗證scope引數存在,並且包含 openid scope值。(如果沒有 openid scope值,請求可能仍然是一個有效的OAuth 2.0的要求,但不是一個OpenID Connect請求。)

3、授權伺服器必須驗證所有必需的引數存在,以及他們的使用符合本規範。

4、如果sub(主題)宣告請求一個特定的值的ID Token,授權伺服器只會傳送一個肯定的響應,如果終端使用者確認sub值是具有一個與授權伺服器活躍的會話或已經通過驗證的請求的結果。授權伺服器不必為不同的使用者回覆ID 令牌或Access Token,即使他們有活動的會話與授權伺服器。如果有這樣的要求,可使用 id_token_hint 引數或通過請求一個特定的在5.5.1節描述的宣告值。如果宣告引數支援實現。

 OAuth 2.0 (RFC6749)指明授權伺服器應該忽略未識別的請求引數。

如果授權伺服器遇到任何錯誤,它必須返回一個錯誤的響應,參看 3.1.2.6節 。

3.1.2.3授權伺服器驗證使用者(Authorization Server Authenticates End-User)

如果請求是有效的,根據使用的請求引數值,授權伺服器嘗試對終端使用者進行驗證或確定終端使用者驗證。授權伺服器所使用的對終端使用者進行驗證的方法(如使用者名稱和密碼,會話cookie,等等)。超出了本規範的範圍。授權伺服器根據請求引數值使用和所使用的驗證方法顯示驗證使用者介面。

在下列情況下授權伺服器必須嘗試驗證終端使用者:

  • 終端使用者沒有進行驗證。
  • 驗證請求包含登入提示引數值。在這種情況下,授權伺服器必須重驗證終端使用者,即使終端使用者已經通過驗證。

授權伺服器在下列情況下不應與使用者互動:

  • 驗證請求沒有任何包含登入提示引數值。在這種情況下,如果一個終端使用者不是已經通過認證或不能隱式的通過驗證,授權伺服器必須返回一個錯誤。

與終端使用者互動時,授權伺服器必須採取適當的措施防範跨站點請求偽造和“點選劫持”如OAuth 2.0 [RFC6749] 10.12和10.13章節描述的那樣。

3.1.2.4授權伺服器獲得使用者同意/授權(Authorization Server Obtains End-User Consent/Authorization)

一旦對終端使用者進行驗證,在對依賴方科放資訊之前授權伺服器必須獲得一個授權決定。當使用的請求引數被許可,就可以與終端使用者通過互動式對話,使它清楚已同意或通過建立通過條件處理請求下同意,其他方式(例如:通過以前的管理許可)。在 2 和 5.3資訊釋出機制部分描述。

3.1.2.5成功的驗證響應(Successful Authentication Response)

一個驗證響應,是從RP發出的授權請求,並由OP的授權終結點響應的OAuth 2.0授權響應訊息。

當使用授權碼流,授權響應返回由OAuth 2.0 (RFC6749) 4.1.2節中定義的引數,通過新增查詢引數 redirect_uri 中指定的授權請求,使用application/x-www-form-urlencoded格式,除非指定不同的響應模式。

下面是一個成功的響應使用此流程非規範化的例子:

  HTTP/1.1 302 Found

  Location: https://client.example.org/cb?

    code=SplxlOBeZQQYbYS6WxSbIA

    &state=af0ifjsldkj

實現例子中關於授權碼內容,參看15.5.1節 。