SSO裏面的SAML和OIDC到底講了啥

本文首發於個人博客 https://teobler.com 轉載請註明出處

SSO是什麼

在瞭解SSO是什麼以前,咱們須要搞清楚兩個概念: Authentication & Authorizationhtml

Authentication(又被稱爲AuthN,身份驗證),它指的是 the process of verifying that "you are who you say you are",也就是說這個過程是爲了證實你是你。一般來講有這麼幾個方式:瀏覽器

  • Single-factor - 也就是能夠經過單一的因素證實」你是你「,好比密碼、PIN碼
  • Multi-factor - 有時候 Single-factor 沒有辦法保證」你是你「,就會須要一些多重驗證的手段,好比動態口令、生物識別等
  • 上面提到的是兩種用的比較多的手段,還有一些其餘的,好比安全問題,短信,email認證等等

Authorization(又被稱爲AuthZ,權限驗證),他指的是 the process of verifying that "you are permitted to do what you are trying to do",也就是說這個過程是爲了證實你是否擁有作這件事的權限,好比修改某個表格等等,若是沒有權限的話一般會返回 403 錯誤碼。安全

SSO 出現以前,用戶在不一樣的系統登陸就須要在不一樣的系統註冊多個帳號,而後須要本身記住多個用戶名和密碼,而若是這些系統是同一個平臺的話,其實該平臺還須要維護多套幾乎如出一轍的登陸系統,給用戶和平臺都帶來了負擔。服務器

SSO 就是一種authentication scheme(身份驗證方案),SSO 容許用戶使用同一個帳戶登陸不一樣的系統,很好地解決了上述的問題。它不但能夠實現單一平臺的登陸,假如某個平臺以外的系統是信任該平臺的,那麼外部系統也能夠集成這個平臺的 SSO, 好比如今的大多數網站都提供了 Google 帳號登陸的功能。微信

要實現 SSO,首先須要你正在開發的系統信任這個第三方登陸系統所提供的用戶信息,而後你須要按照必定的標準和協議去與其對接,接下來咱們會介紹兩個比較經常使用的 SSO 協議 -- SAML 2.0 和 OIDC。session

SAML 2.0

SAML 2.0是什麼

SAMLSecurity Assertion Markup Language 的簡稱,是一種基於XML的開放標準協議,用於在身份提供者(Identity Provider簡稱IDP)和服務提供商(Service Provider簡稱SP)之間交換認證和受權數據。ide

SAML 2.0是該協議的最新版本,於2005年被結構化信息標準組織(OASIS)批准實行。post

流程

SAML flow

  1. 用戶要訪問SP上面的資源,可是SP要求提供用戶身份信息
  2. SP 會將用戶跳轉到 IDP,IDP 返回一個登錄頁面
  3. 用戶成功登錄後IDP會提供一個 SAML Assertion,經過用戶端傳遞給SP
  4. 此時SP會驗證這個 SAML Assertion,沒有問題的話就會返回相應的資源
  5. 若是後面用戶又要訪問該平臺的另一個系統,因爲該用戶已經在IDP那邊登陸過了,因此這次訪問IDP就可以直接將用戶的 SAML Assertion 傳遞給這個新的SP,即可以實現不登陸直接訪問資源

SAML Assertion

那麼這個 SAML Assertion 又是個啥呢?網站

首先用戶爲何能夠訪問SP上的資源呢?確定是由於其實SP也有一份用戶的資料,這個資料裏面可能有用戶的帳戶信息,權限等等,可是如今用戶的信息是由IDP提供的,因此如今須要作的就是講兩份用戶信息映射起來,好讓SP知道IDP提供的用戶究竟是哪個。加密

而這個映射的約定,就是SP和IDP進行集成的時候的一個配置,這個配置叫作 metadata。這個配置有兩份,兩邊各一份,裏面約定了應該怎麼去映射用戶信息,簽名的證書等。IDP和SP會經過別的方式去交換這兩份 metadata

因此其實 SAML Assertion 裏面包含了用戶的惟一標識,可以證實該用戶是誰。在SP拿到這份信息後就會按照一些規則去驗證裏面的信息是不是合法的用戶。

那麼問題來了,若是中間人知道了咱們之間的規則隨便塞了一份信息進來咋辦?因此其實 SAML Assertion 裏面除了用戶信息其實還有IDP的簽名,只有SP先解析了裏面的簽名確認無誤以後纔會信任這份信息。

知道了 SAML Assertion 是個啥之後,咱們還須要弄清楚它是怎麼發送出去的。要弄清楚它們是怎麼發送出去的咱們須要知道一個東西叫作 binding method

SAML 2.0 有許多不一樣的 binding,它們其實就是 SAML Assertion 的交互方式:

  • HTTP redirect binding
  • HTTP POST binding
  • HTTP artifact binding
  • SAML URI binding
  • SAML SOAP binding(based on SOAP 1.1)
  • reverse SOAP(PAOS) binding

其中如今用的比較多的是前三種,它們都是基於HTTP協議來實現的。

  • redirect binding是在SP redirect到IDP的時候會在URL中帶上請求信息,好比id,誰發出來的等等
  • POST binding是爲了解決redirect方式在使用過程當中的一些問題而產生的,好比URL過長,response不安全等等
  • artifact能夠看作一個引用,這個引用會經過瀏覽器帶到SP那邊,SP拿到以後再經過裏面的信息去IDP拿相應的 SAML Assertion

metadata

上面提到過 metadata 是爲了讓IDP和SP明白彼此交流的信息,而且有一些安全考慮,裏面主要的信息有:

  • NameFormat -- 約定用戶ID的格式,好比 email address, transient等等
  • Certificate -- 解析簽名,加密assertion
  • Entity identifier -- 該metadata的惟一標識符
  • Binding -- 使用何種方式通訊

其中有一個字段 md:KeyDescriptor 在SP中有一個 encryption,在SP和IDP進行通訊創建信任的時候,IDP就會拿到SP加密的key,在用戶登陸成功後,IDP就會用這個key加密 SAML Assertion,SP拿到後經過本身的私鑰進行解密。另外一個叫 signing 的字段會被用來解析對方的簽名,用來辨別這個 Assertion 是否是我想要的人發過來的。

OIDC

OIDC是什麼

OpenID Connect(OIDC) 是創建在 OAuth 2.0 協議之上的一個簡單的身份層,它容許計算客戶端根據受權服務器執行的認證,以 JSON 做爲數據格式,驗證終端用戶的身份。它是 OpenID 的第三代規範,前面分別有 OpenID 和 OpenID 2.0。它在OAuth 2.0 的基礎上增長了 ID Token 來解決第三方客戶端標識用戶身份認證的問題。

它的結構如圖所示:

image-20200601085202978

從它的結構圖中能夠看出,除了核心實現外,OIDC 還提供了一系列可選的擴展功能。好比:

  • Discovery:發現服務,使客戶端能夠動態的獲取 OIDC 服務相關的元數據描述信息(好比支持那些規範,接口地址是什麼等等)
  • Dynamic Registration :可選。動態註冊服務,使客戶端能夠動態的註冊到OIDC的OP
  • Session Management :Session管理,用於規範OIDC服務如何管理Session信息
  • OAuth 2.0 Form Post Response Mode:針對 OAuth2 的擴展,OAuth2 回傳信息給客戶端是經過URL的 querystring 和 fragment 這兩種方式,這個擴展標準提供了一基於 form 表單的形式把數據 post 給客戶端的機制

因爲圖片距今已經有些年限了,其實如今OIDC還提供了許多可選的擴展,具體可到官網查看。

流程

因爲 OIDC 是基於 OAuth 2.0 的,因此 OIDC 也擁有多種 flow。因爲篇幅所限我這裏會相對詳細地解釋 Authorization Code Flow,在開始前咱們須要弄清楚幾個名稱:

  • EU:End User,指使用終端(瀏覽器等)訪問服務器資源的用戶
  • RP:Relying Party,用來代指 OAuth2 中的受信任的客戶端,身份認證和受權信息的消費方,至關於 SAML 中的 SP
  • OP:OpenID Provider,有能力提供EU認證的服務(好比OAuth2中的受權服務),用來爲RP提供EU的身份認證信息,至關於 SAML 中的 IDP
  • ID Token:JWT格式的數據,包含 EU 身份認證的信息。ID Token 由 JWS 進行簽名和 JWE 加密,從而提供認證的完整性、不能否認性以及可選的保密性。裏面可能會有不少字段,詳細能夠看這裏,其中這幾個字段是必定包含其中的

    • iss - Issuer Identifier:提供認證信息者的惟一標識,一般是一個 HTTPS 的 URL
    • sub - Subject Identifier:iss 提供的 EU 的標識,在 iss 範圍內惟一,它會被 RP 用來標識惟一的用戶,最長爲255個ASCII個字符
    • aud - Audience(s):標識ID Token的受衆,必須包含 OAuth 2.0 的client_id
    • exp - Expiration time:過時時間,超過此時間的 ID Token 會做廢再也不被驗證經過
    • iat - Issued At Time:JWT的構建的時間
  • UserInfo Endpoint:用戶信息接口(受OAuth2保護),當RP使用Access Token訪問時,返回受權用戶的信息,此接口必須使用HTTPS
  • APP Token:一般來講 OP 提供的用戶信息和 Access Token 中包含的信息不帶有用戶在 RP 中的權限,RP 一般會本身生成一個 token 給 EU 做爲後續訪問資源的用戶證實

Authorization Code flow

Authorization Code flow

  1. EU 訪問 RP 的資源可是沒有進行身份認證
  2. RP 將 EU redirect 到 OP 端,並帶上一些參數,這裏列舉一些必選參數,還有許多可選參數能夠看這裏

    • client_id:惟一標識
    • scope:請求權限範圍,OIDC的請求必須包含值爲「openid」的scope的參數
    • response_type:要求 OP 的返回值,值爲 codetokenid_tokennone 中的一個或幾個,在當前 flow 值爲 code
    • redirect URL:認證完成後的跳轉URL
    • state:當前登陸認證操做的一個隨機 query,用於防止 CSRF 或 XSRF 攻擊
  3. 而後 OP 會驗證 EU 的身份信息,一般會詢問用戶是否將本身的信息提供給 RP,確認後進行登陸操做
  4. 登錄成功後 OP 會將 EU redirect 到剛剛 RP 提供的 URL,同時會在 URL 中帶上一個 Authorization Code 和剛剛的 state 參數
  5. 以後 RP 拿到 code 和 state,先確認是否是相同的 state 保證此次通訊是有效的,以後再經過 POST 請求從 OP 獲取 token,裏面包含 ID Token,Access Token,Refresh Token,Token Type,Expired In 等信息
  6. 以後 RP 會驗證 ID Token驗證 Access Token 確保它們沒有問題
  7. 而後 RP 經過 Access token 經過 OP 提供的 UserInfo Endpoint 獲取用戶信息,拿到用戶信息後與本身的用戶信息進行比對
  8. 最後返回一個 APP Token 到 EU

Implicit Flow

Implicit Flow 是在 OP redirect EU 到 RP 的時候會帶上 ID Token 和 Access Token(若是必要) 而不是 Authorization Code,同時在發送請求的時候也會有一些不一樣,須要帶上一些別的參數,這裏就不細講了,總的流程是差很少的,詳情能夠查看這裏

Hybrid Flow

Hybrid Flow 能夠理解爲上面兩個 flow 的結合,OP redirect EU 到 RP 的時候會帶上 Authorization Code,同時根據發送請求時候 Response Type 參數的不一樣還會帶上一些別的參數,具體流程能夠參考這裏


很是感謝你能看到這裏,若是你以爲有幫助到你,能夠關注個人微信公衆號
gongzhonghao.jpeg

相關文章
相關標籤/搜索