天天看點

Identity Server 4 預備知識 -- OpenID Connect 簡介

本文介紹的比較粗略.

我之前的文章簡單的介紹了OAuth 2.0 (在這裡: https://www.cnblogs.com/cgzl/p/9221488.html), 還不是很全.

這篇文章我要介紹一下 OpenID Connect.

OAuth 2.0 不是身份認證(Authentication)協定. 為什麼有人會認為OAuth 2.0具有身份認證的功能? 這是因為OAuth2經常作為身份認證(Authentication)協定的一部分來使用. 例如在典型的OAuth2流程裡, OAuth2經常會嵌入一些身份認證的事件.

那麼身份認證(Authentication)是什麼?

我們這裡所說的身份認證就是指它可以告訴應用程式目前的使用者是誰, 還有這些使用者是否正在使用你的應用程式. 它是一種安全架構, 它可以告訴你使用者是他們所聲明的身份, 通常呢, 是通過提供一套安全憑據(例如使用者名和密碼)給應用程式來證明這一點.

而OAuth2則不管使用者這些東西, OAuth2的用戶端應用隻考慮請求token, 得到token, 使用token通路API. 它不關心誰給用戶端應用授權了, 也不關心是否有最終使用者.\

引用《OAuth 2.0 in Action》裡面的一個比喻來解釋, 把身份認證看作是軟糖, 而授權是巧克力. 這兩種東西感覺略有相似, 但是本質上卻截然不同: 巧克力是一種原料, 而軟糖是一種糖果. 可以使用巧克力作為主要原料做出巧克力口味的糖果, 但是巧克力和軟糖絕不是等價的.

盡管巧克力可以單獨作為一種最終産品, 但在這個比喻裡巧克力是一種非常有用原料, 它極具多樣性, 可以用來做蛋糕, 冰激淩, 雪糕等等.

在這個比喻裡 OAuth 2.0 就是巧克力, 它是衆多web安全架構的一種多用途的基本成分.

而軟糖, 是一種糖果. 有一種特别可口的軟糖叫做巧克力軟糖. 很顯然, 巧克力在這種軟糖裡是主要成分, 但是它還需要其它原料成分和一些關鍵的流程把巧克力轉化成巧克力軟糖.

制做出的産品是軟糖的形式, 它以巧克力為主要成分. 這叫使用巧克力來制作軟糖, 是以說巧克力不等價于軟糖.

在這個比喻裡, 身份認證就更像軟糖, 它需要一些關鍵的元件和流程, 而卻要把這些元件和流程通過正确的組合起來并安全的使用, 針對這些元件和流程還是有很多的選項的.

可以說我們要制作巧克力軟糖, 也就是需要一個基于OAuth2的身份認證協定. 而OpenID Connect就是這樣的開放标準, 它可以工作于不同的身份供應商之間. OpenID Connect 基于 OAuth 2.0, 在此之上, 它添加了一些元件來提供身份認證的能力.

OpenID Connect的官方定義是: OpenID Connect是建立在OAuth 2.0協定上的一個簡單的身份辨別層, OpenID Connect 相容 OAuth 2.0. 

想要基于OAuth2建構身份認證協定, 那麼就需要把OAuth2裡面的那些角色映射到身份認證的事務裡面.

在OAuth2裡面, 資源所有者(Resource Owner)和用戶端應用(Client)經常在一起工作, 因為用戶端應用代表了資源所有者. 而授權伺服器(Authorization Server)和被保護的資源(Protected Resource)經常在一起, 因為授權伺服器生成token, 而被保護的資源接收token. 是以說在最終使用者/用戶端應用 與 授權伺服器/被保護資源 之前存在一個安全和信任的邊界, 而OAuth2就是用來跨越這個邊界的協定.

而在身份認證的事務裡, 最終使用者使用身份提供商(Identity Provider, IdP)登入到依賴方(Relying Party, RP, 可以了解為用戶端).

總結一下前面這段話:

OAuth2裡可以分為兩部分: 1.資源所有者/用戶端應用, 2.授權伺服器/被保護資源.

身份認證協定裡也是兩大部分: 1.依賴方, 2.身份提供商.

是以考慮這樣映射:

OAuth2裡的授權伺服器/被保護資源 ---- 身份認證協定裡的身份提供商進行映射

OAuth2裡面的資源所有者 ---- 身份認證協定裡的最終使用者

OAuth2的用戶端應用 ---- 身份認證協定裡的依賴方(RP).

Identity Server 4 預備知識 -- OpenID Connect 簡介

OAuth2裡, 資源所有者的權限會委派給用戶端應用, 但這時該權限對應的被保護資源就是他們自己的身份資訊. 也就是說他們授權給依賴方(RP), 讓其可以知道現在是誰在使用應用, 而這就是身份認證事務本質.

依賴方現在就可以知道是誰在使用系統并且他們是如何登入進來的. 不過這裡還需要用到另外一種token, 叫做ID token, 這種token攜帶着身份認證事件本身的資訊.

那麼為什麼不使用OAuth2裡的access token把這些事都一次性解決了呢? 

因為首先access token不含有任何關于身份認證的資訊; 其次access token的生命期可能會非常的長, 即使使用者離開了它仍有可能有效, 它還有可能被用于無最終使用者參與的情況; 還有一種情況就是access token可能會被其它的用戶端應用借用. 是以, 無論用戶端是如何得到的access token, 它都無法從access token裡得到最終使用者的資訊以及最終使用者的身份認證狀态.

在OAuth2裡, access token不是為用戶端準備的, 它對于用戶端應該是不透明的, 但是用戶端也需要從access token得到一些使用者資訊. 實際上用戶端應用隻是access token的展示者, access token真正的目标觀衆是被保護的資源.

在OpenID Connect裡, 這個第二個叫做ID Token, 它會和access token一同發送給用戶端應用.

OpenID Connect是由OpenID基金會于2014年釋出的一個開放标準, 簡單的說就是, 它使用OAuth2來進行身份認證. OpenID Connect直接建構于OAuth2.0的基礎之上, 與其相容. 通常OpenID Connect是和OAuth2一同部署來使用的.

OpenID Connect的整體抽象流程如下圖所示: 

Identity Server 4 預備知識 -- OpenID Connect 簡介

1. 依賴發(RP)發送請求到OpenID提供商(OP, 也就是身份提供商).

2. OpenID提供商驗證最終使用者的身份, 并獲得了使用者委派的授權

3. OpenID提供商傳回響應, 裡面帶着ID Token, 也通常帶着Access Token.

4. 依賴方現在可以使用Access Token發送請求到使用者資訊的端點.

5. 使用者資訊端點傳回使用者的聲明(claims, 相當于是使用者的資訊).

OpenID Connect的ID Token 和使用者資訊端點以後在使用Identity Server 4的時候在進行介紹.

OpenID Connect 會負責身份認證這個動作, 也就是把最終使用者登入到系統, 或者判斷最終使用者是否已經登入了. OpenID Connect會通過一種安全的方式從伺服器把身份認證的結果傳回給用戶端, 這樣用戶端就可以依賴于它了. 也是因為這個原因, 用戶端被稱為了依賴方(RP). 這個身份認證的結果就是ID Token.

OpenID Connect身份認證有三個路徑(三個流程, flow): Authorization Code 流程, Implicit 流程, Hybrid 流程.

在Authorization Code 流程裡, 一個授權碼(Authorization Code)會被傳回給用戶端. 這個授權碼可以被直接用來交換ID Token和Access Token. 該流程也可以在用戶端使用授權碼兌換Access Token之前對其身份認證. 但是該流程要求用戶端的身份認證動作在背景使用client id和secret來獲得tokens, 這樣就不會把tokens暴露給浏覽器或其它可通路浏覽器的惡意應用了.

這種流程要求用戶端應用可以安全的在它和授權伺服器之間維護用戶端的secret, 也就是說隻适合這樣的用戶端應用.

它還适合于長時間的通路(通過refresh token).

Authorization Code流程的授權碼來自于授權端點, 而所有的tokens都來自于Token端點. 

Authorization Code流程的步驟如下:

用戶端準備身份認證請求, 請求裡包含所需的參數

用戶端發送請求到授權伺服器

授權伺服器對最終使用者進行身份認證

授權伺服器獲得最終使用者的同意/授權

授權伺服器把最終使用者發送回用戶端, 同時帶着授權碼

用戶端使用授權碼向Token端點請求一個響應

用戶端接收到響應, 響應的body裡面包含着ID Token 和 Access Token

用戶端驗證ID Token, 并獲得使用者的一些身份資訊.

Implicit流程在請求token的時候不需要明确的用戶端身份認證, 它使用重定向URI的方式來驗證用戶端的身份. 因為這一點, refresh token也就無法使用了, 這同樣也不适合于長時間有效的access token.

在Implicit流程裡, 所有的tokens都來自于授權端點, 而Token端點并沒有用到.

該流程主要用于浏覽器内的應用, Access Token和ID Token一同被直接傳回給用戶端. 因為這個原因, 這些tokens也會暴露于最終使用者和可以通路該浏覽器的其它應用了. 

它并不适合于長時間的通路.

Implicit流程的步驟如下:

授權伺服器把最終使用者發送回用戶端, 同時帶着ID Token. 如果也請求了Access Token的話, 那麼Access Token也會一同傳回.

Hybrid流程是前兩者的混合, 在該流程裡, 有一些tokens和授權碼來自于授權端點, 而另外一些tokens則來自于Token端點.

該流程允許用戶端立即使用ID Token, 并且隻需要一次往返即可獲得授權碼.

這種流程也要求用戶端應用可以安全的維護secret.

它也适合于長時間的通路.

Hybrid流程的步驟如下:

授權伺服器把最終使用者發送回用戶端, 同時帶着授權碼, 根據響應類型的不同, 也可能還帶着一個或者多個其它的參數.

Authorization Code Flow

Implicit Flow

Hybrid Flow

所有的tokens都來自于授權端點

no

yes

所有的tokens都來自于Token端點

Tokens對浏覽器隐藏

用戶端可以被認證

可以使用Refresh Token

隻需一次往返通信

大部分通信都是伺服器對伺服器

看情況

<col>

"response_type" 的值

Flow

code 

id_token 

id_token token 

code id_token 

code token 

code id_token token 

本文就簡單介紹這些, OAuth 2.0 和 OpenID Connect 其餘涉及到的内容會在後續Identity Server 4的系列文章裡介紹.