程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> WebSphere >> WebSphere Application Server SAML Trust Association Interceptor簡介

WebSphere Application Server SAML Trust Association Interceptor簡介

編輯:WebSphere

簡介

IBM WebSphere Application Server(以及在 WebSphere Application Server 平台之上運行的一堆產品)自 V5.1 以來就有一個基於 Trust Association Interceptor (TAI) 接口的可自定義的身份驗證框架。該接口有多種產品實現。2012 年,WebSphere Application Server 完整配置文件版本提供了一個新的 SAML(Security Assertion Markup Language,安全斷言標記語言)TAI,它可用於 WebSphere Application Server 7.0、8.0 和 8.5 之上。(撰寫本文之時,IBM WebSphere Application Server Liberty 配置文件還不支持 SAML。)這個 TAI 是目前最全面的 TAI。本文將介紹:

如何使用 SAML TAI。

何時適合使用 SAML TAI。

各種 SAML TAI 屬性如何配合使用。

SAML TAI 穿梭於 WebSphere Application Server 授權流程中時使用的錯綜復雜的路徑。

本文假設您已牢牢掌握 WebSphere Application Server 身份驗證流程(如文章 WebSphere Application Server 中的高級身份驗證 中所述),而且了解:

數字簽名

加密

身份斷言

TAI 的大體知識。

基礎:Web 單點登錄用例

SAML TAI 引入了對新的 Web 單點登錄 (SSO) 形式的支持。正如我們在 WebSphere Application Server 安全類中所說的,術語 “SSO” 在行業中被嚴重過度使用,所以我們的 SSO 用例將非常嚴格。

SAML 多年來已發生演變。SAML 2.0 規范定義了一些配置文件和綁定:

SAML 配置文件描述了 SSO 交互中的各個參與方之間的不同消息交換序列。

SAML 綁定描述了如何將一條特定的消息綁定到某個協議。在配置文件的消息交換序列中的任意步驟中,配置文件都可以引用一個或多個綁定作為轉發消息的方式選擇。

SAML 配置文件包括:

SSO 配置文件                    

Web Browser SSO Profile

Enhanced Client or Proxy Profile

Identity Provider Discovery Profile

Single Logout Profile

Name Identity Management Profile

Artifact Resolution Profile

Assertion Query/Request Profile

Name Identifier Mapping Profile

SAML Attribute Profiles

SAML 綁定包括:

SAML SOAP Binding

Reverse SOAP Binding

HTTP Redirect Binding

HTTP Post Binding

HTTP Artifact Binding

SAML URI Binding

WebSphere Application Server 從修復包 7.0.0.7 開始支持通過 SAML SOAP Binding 來支持 SOAP。SAML TAI 是在修復包 7.0.0.23、8.0.0.5 和基礎產品的 8.5.0.0 版中引入的。SAML TAI 僅支持結合使用 Web Browser SSO Profile 和 HTTP Post Binding。  

可以看到,這只是許多可能的用例中的一種。事實上,確實存在兩種變體。在介紹它們之前,我們先介紹一下所涉及的角色:

身份提供程序 (IdP)

服務提供程序 (SP) 有時稱為中繼方 (Relying Party) 或 RP。

IdP 的工作是驗證最終用戶(IdP 完成此操作的准確方式無關緊要),並生成一些關於用戶的斷言或聲明。這些斷言由 IdP 進行數字簽名。SAML 規范定義了這些斷言的格式。SP 接收斷言,如果它對來自受信任的 IdP 的斷言感到滿意,則基於斷言的某些部分來讓用戶登錄。

我們還將查看一個基於真實用例的示例。Unified Assurance Company (UAC) 有許多企業客戶;舉例而言,Gamma Business Machine (GBM) 公司、Omicron Lumber Company 和 Purple Maple Syrup Company。我們將這 4 個(虛構的)公司視為位於一個 SSO 連鎖中。在此示例中,Unified Assurance Company 了解這 3 個連鎖成員的員工(UAC LDAP 中有針對外部連鎖成員的員工的用戶條目)。但是,UAC LDAP 中沒有連鎖成員的密碼。

在這種情況下,Unified Assurance 希望將一個 IBM WebSphere Portal 系統提供給它的外部和內部用戶。來自 GBM 的用戶將向 GBM 中的一個系統進行驗證,Omicron Lumber 用戶向 Omicron Lumber 網絡中的一個系統進行驗證,而 Purple Maple Syrup 用戶向 Google 托管的一個系統進行驗證。(在本例中,對 WebSphere Portal 系統的使用只是偶然情況。)

圖 1. SSO 連鎖示例

該示例表明,用戶登錄到其 IdP 的詳細信息與 United Assurance 不相關。舉例而言,GBM 用戶可通過一個登錄表單進行登錄,Omicron Lumber 用戶使用 SPNEGO 身份驗證自動將其憑據提供給 IdP,而 Purple Syrup 用戶使用 SSL 客戶端證書向其 IdP 進行驗證。

另請注意,有一組彩色的私鑰/公鑰對。每個 IdP 都擁有自己的私鑰,SP 在其 IdPTruststore 中保存了與這些私鑰對應的所有相應公共證書的副本。

Web Browser SSO Profile 描述了如何通過 HTTP 重定向在用戶的浏覽器中傳輸 SAML 斷言。針對 Web Browser SSO 的 HTTP Post Binding 可能有兩種用例:浏覽器請求首先傳到 IdP,或者浏覽器請求首先傳到 SP。我們將前一種用例稱為 IdP 發起的 Web SSO(圖 2)。

圖 2. IdP 發起的 Web SSO

在 IdP 發起的 Web SSO 用例中:

用戶訪問 IdP 上的一個 URL 鏈接來啟動該過程。正如前面所討論的,用戶向 IdP 進行驗證。

基於 IdP 中的配置和提供給 IdP 的原始 URL,創建一個 SAML 響應,並通過 HTTP Post 重定向將它發送給 SP 中的一個 Assertion Consumer Service (ACS)。這個 SAML 響應由 IdP 進行簽名。

SAML TAI 使用了 SAML 響應並讓用戶進行登錄。在此示例中,用戶身份存在於 UAC LDAP 中。但應注意的是,這不是 SAML Web SSO 所必需的。在內存中創建一個 JAAS 主題,還要創建各種 WebSphere Application Server 安全令牌,包括一個 SSOToken(也稱為 LtpaToken2)。根據這個 SSOToken 創建一個 LtpaToken2。

在用戶登錄後,請求被分派到 ACS。這個應用程序的惟一用途是在使用 SAML TAI 讓用戶登錄後,將用戶重定向到正確的登錄頁面。ACS 定義了一個 Java EE 安全約束,以便調用 WebSphere Application Server 容器安全性和 SAML TAI。作為對 SAML TAI 的支持的一部分,還發布了一個 ACS 應用程序。如果願意的話,可以將您的業務應用程序修改為包含 ACS 功能,添加一個接受 HTTP POST 的新 servlet。然後在下一步中,該 servlet 會被 “轉發” 到正確的 “登錄” 頁面,而不是執行重定向。

ACS 將用戶重定向到應用程序的登錄頁面(可能基於請求中的某部分信息,或者基於配置)。在本示例中,這個 URL 為:https://benefits-portal.uac.com/wps/myportal。這個 HTTP 重定向包含新的 LtpaToken2 cookie。浏覽器轉到重定向路徑,並重新發送 LtpaToken2。

然後會再次調用 SAML TAI,這一次檢查請求中是否有一個 SAML 響應。如果沒有,但有一個 LtpaToken2 cookie,則會執行標准的 Web Inbound 登錄配置處理(稍後將介紹)。

此方法的一個限制是,用戶需要調用一個由 IdP 托管的 URL 的 GET 鏈接。請考慮以下示例:GBM 的用戶需要知道用於登錄到 UAC Portal 的特定於 GBM 的 URL,Omicron 員工需要知道(不同的)Omicron URL,而 Purple Maple Syrup 員工需要知道(不同的)Purple Maple Syrup URL。在每組用戶登錄到 UAC Portal 後,都會登錄到 https://benefits-portal.uac.com/wps/myportal。

此方法的另一個限制是,一個 IdP 可用於為多個服務提供程序驗證用戶。GBM 用戶還可以使用同一個 SSO IdP 登錄到與 GBM 有業務關系的汽車租賃系統。但是,(從用戶角度講)UAC Portal 和汽車租賃系統的 URL 托管在同一個 GBM IdP 服務器上。用戶可能將它們混淆。

為了解決這些限制,服務提供程序常常會開發品牌認知。無論用戶來自哪個連鎖合作伙伴。每個用戶都可以單擊一個包含 https://benefits-portal.uac.com 的鏈接。用戶首先將浏覽器定向到服務提供程序,然後服務提供程序會啟動 SSO 流程。WebSphere Application Server SAML TAI 支持第二種用例;通過配置,SAML TAI 將用戶重定向到 IdP。我們將此稱為 SP 重定向到 IdP Web SSO 用例(圖 3)。

圖 3. SP 重定向到 IdP

在 SP 重定向到 IdP Web SSO 用例中:

用戶訪問 SP 上的應用程序 URL 鏈接來啟動該過程。在此示例中,這個鏈接為 https://benefits-portal.uac.com/wps/myportal。

SAML TAI 將被調用兩次。因為這個 URL 不是 ACS,所以 TAI 最初不會解釋請求。Web Inbound 配置尋找一個 LtpaToken2 cookie。沒有找到。第二次調用 SAML TAI。基於傳入請求中的一些數據和 TAI 配置,TAI 返回一個重定向到正確 IdP 的 HTTP 302 代碼(稍後將討論如何確定任何特定請求的正確 IdP)。TAI 設置一個 cookie。這個 cookie 被設置為原始 referrer URL 的值,在本示例中為 https://benefits-portal.uac.com/wps/myportal。如上面所討論的,用戶向 IdP 進行驗證。

第 3 到 7 步與 “IdP 發起的 Web SSO” 用例中第 2 到 6 步相同。

WebSphere Application Server SAML TAI

為了在 WebSphere Application Server V8.5(以及 7.0 和 8.0 版)中實現 SAML Web SSO 功能,該功能使用了一個 Trust Association Interceptor (TAI) 來實現。(這篇文章 全面討論了 WebSphere Application Server TAI。)SAML TAI 的完整類名為 com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor。以下方面會影響 SAML Web SSO TAI:

必須啟用管理安全性。

SAML TAI 可在全局上或在其他安全域定義。

配置 SAML TAI 的域必須啟用應用程序安全性。它還必須啟用 TAI,並配置了 SAML TAI。

在用戶登錄到 WebSphere Application Server 期間,SAML TAI 將來自 POST 請求的 SAML 斷言的副本保存在用戶的主題(例如用於出站 Web 服務調用)的私有憑據中。

Subject Attribute Propagation

必須啟用,這些(未存儲在 User Registry 中的)自定義信息才能在單元中的服務器之間傳播。因為這些 SAML 斷言無法從 WebSphere Application Server 注冊表中獲得,所以為主題定義了一個適當的自定義緩存鍵。(主題傳播、自定義緩存鍵和 TAI 的微妙影響不屬於本文的討論范疇。請參閱 這篇文章,了解全面的介紹。)

SAML TAI 支持多個應用程序,每個應用程序可以有自己的 ACS URL。

每個應用程序可與多個 IdP 交互。每個 IdP 可能夠以不同的方式進行配置。

SAML TAI 僅支持 Web SSO Profile 和 HTTP Post Binding。

重要的是全面理解最後一點,這一點的衍生結果是,僅有一個 HTTP POST 消息從 IdP 流到 WebSphere Application Server SAML TAI,該消息在 POST 正文中包含 SAML Response 對象。WebSphere Application Server SAML TAI 基於這個 SAML Response 對象來記錄用戶,返回一個 LtpaToken2 cookie。配置文件和綁定適合到達應用程序的經過驗證的登錄頁面。來自浏覽器的後續交互基於 HTTP 客戶端(通常為用戶的浏覽器)返回的 LtpaToken2 cookie 來維護用戶的登錄上下文。

我們提出這一點是為了指出,盡管該 POST 中包含的 SAML 斷言允許使用稍微 “可移植的” 令牌,但這個可移植的令牌會迅速被一個特定於 WebSphere 的 LtpaToken2 cookie 取代。這個模型通過浏覽器很好地提供給用戶。但它不能很好地提供給其他沒有 “登錄到登錄頁面並通過 cookie 維護登錄狀態” 模型的 HTTP 應用程序客戶端。例如,如果某個 RESTful Web 服務應用程序想要使用所有 HTTP 方法(GET、PUT、POST 和 DELETE),那麼必須構造它來實現以下操作:

確定應用程序是否有一個 LtpaToken2 cookie。

如果沒有,則獲取一個 SAML 響應,並跟隨從定向的 POST 訪問 ACS,使客戶應用程序能夠獲得一個 LtpaToken2 cookie。

只有成功執行上述兩步後,才能執行應用程序希望首先調用的真實的 Web 服務操作。

由於主題和 LtpaToken2 中的自定義緩存鍵,必須啟用主題屬性傳播,以便在 WebSphere SSO “單元” 中的 JVM 之間實現完整用戶身份的傳播。這可包含對用戶登錄到的原始服務器的 JMX 回調。

SAML TAI 和 Web 入站登錄配置

這篇文章中的圖 20 所示的邏輯流已在圖 4 中進一步完善,以支持 SAML TAI。如果用戶有一個 LtpaToken2 cookie,而且浏覽器使用一個新的 SAML 斷言向 ACS 發出 POST 請求,那麼原始 LtpaToken2 cookie 必須忽略,而且應在創建新主題時使用來自 SAML 斷言的用戶身份。這一行為更改受一般性的自定義屬性 com.ibm.websphere.security.InvokeTAIbeforeSSO 控制,而該屬性為 SAML TAI 類 (com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor) 的值。如果 SAML TAI 是在全局基礎上定義的,則將這個自定義屬性添加到 Global Security 頁面上。如果 SAML TAI 是在一個安全域中定義的,則將這個自定義屬性添加到該安全域的 Custom Properties 上。

新邏輯流的第一部分如圖 4 所示。

圖 4. SAML TAI 在 LtpaToken2 之前處理 SAML Tokens

換言之,如果正確定義了屬性 InvokeTAIbeforeSSO,SAML TAI 會在檢查 SSO Token (LtpaToken2 cookie) 之前被調用。

要支持 SP 重定向到 IdP Web SSO 用例,SAML TAI 可潛在地調用多次,如果沒有 LtpaToken2,並且沒有 SAML 斷言,那麼可以在執行第二個特殊安全屬性 com.ibm.websphere.security.DeferTAItoSSO 時調用 SAML TAI 邏輯,該屬性為 SAML TAI 類的值。此屬性也被定義為 Global Security 頁面上或啟用了 SAML TAI 的安全域的 Custom Properties 上的一個自定義屬性。

如果檢查 SP 重定向到 IdP Web SSO 用例,您可看到,在一些場景中,可在初始登錄時調用 SAML TAI 多次。參見圖 5,了解如何為 SP 重定向到 IdP Web SSO 用例處理 SAML TAI 支持。

圖 5. “SP 重定向到 IdP Web SSO” 的 SAML TAI 支持

將軌跡規范設置為 com.ibm.ws.security.web.saml.*=all 時,檢查軌跡可確認 SP 重定向到 IdP Web SSO 用例期間這兩個流程圖中的邏輯。

為了幫助完成此練習,下面這個示例中有兩個 TAI:一個不會進行攔截、但會在日志中發出一條消息的 FakeTAI(清單 1)。

[3/20/13 16:22:49:635 EDT] 00000024 TrustAssociat A   SECJ0121I: Trust Association Init
class com.ibm.issw.security.FakeTAI loaded successfully
[3/20/13 16:22:49:640 EDT] 00000024 TrustAssociat A   SECJ0122I: Trust Association Init
Interceptor signature: 1.2
[3/20/13 16:22:49:642 EDT] 00000024 TrustAssociat A   SECJ0121I: Trust Association Init
class com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor loaded successfully
[3/20/13 16:22:49:644 EDT] 00000024 ACSTrustAssoc >  initialize Entry

[3/20/13 16:22:49:670 EDT] 00000024 ACSTrustAssoc <  initialize Exit
[3/20/13 16:22:49:670 EDT] 00000024 TrustAssociat A   SECJ0122I: Trust Association Init
Interceptor signature: <null>

在清單 2 中,在處理 SSO 之前調用 SAML TAI。

[3/20/13 16:22:49:673 EDT] 00000024 ACSTrustAssoc >  isFirstPass Entry

[3/20/13 16:22:49:674 EDT] 00000024 ACSTrustAssoc 3   Request does not contain
SAMLResponse, TAI will be skipped and deferred.
[3/20/13 16:22:49:675 EDT] 00000024 ACSTrustAssoc 3   Request is scoped to this TAI.

接下來是 SSO 處理。首先調用 Fake TAI。它沒有進行攔截。然後調用 SAML TAI(清單 3)。

[3/20/13 16:22:49:679 EDT] 00000024 SystemOut     O   FakeTAI.isTargetInterceptor()
returns 'false'
[3/20/13 16:22:49:680 EDT] 00000024 ACSTrustAssoc >  isFirstPass Entry

[3/20/13 16:22:49:697 EDT] 00000024 SAMLTaiState  3   SAML TAI challenge login: Referer
URL cookie set https://oc5067386220.ibm.com:9444/HitCountWeb/HitCountServlet
[3/20/13 16:22:49:697 EDT] 00000024 ACSTrustAssoc <  createTAIErrorResult Exit
[3/20/13 16:22:49:697 EDT] 00000024 ACSTrustAssoc <  invokeTAIafterSSO Exit
[3/20/13 16:22:49:698 EDT] 00000024 ACSTrustAssoc <  negotiateValidateandEstablishTrust
Exit

該軌跡現在處理來自圖 2 的第 3 條消息(清單 4)。

[3/20/13 16:22:56:207 EDT] 00000026 ACSTrustAssoc >  isFirstPass Entry

[3/20/13 16:22:56:212 EDT] 00000026 ACSTrustAssoc 3   Request contains SAMLResponse,
TAI will be processed.

[3/20/13 16:22:56:484 EDT] 00000026 ACSTrustAssoc <  negotiateValidateandEstablishTrust
Exit

用戶登錄。將一個 LtpaToken2 cookie 發送給用戶。因為您使用了內置的 ACS 應用程序,所以 ACS 會將浏覽器重定向到原始 referrer URL cookie 值,也就是 https://oc5067386220.ibm.com:9444/HitCountWeb/HitCountServlet(原始 referrer URL cookie 通過 SAML TAI 來設置。)

圖 2 中的第 6 條消息出現並進入軌跡。再次聲明,在檢查 LtpaToken2 cookie 之前調用 SAML TAI(清單 5)。

[3/20/13 16:22:56:774 EDT] 00000026 ServerCache   I   DYNA1071I: The cache provider
"default" is being used.
[3/20/13 16:22:57:627 EDT] 00000025 ACSTrustAssoc >  isFirstPass Entry

[3/20/13 16:22:57:627 EDT] 00000025 ACSTrustAssoc 3   Request does not contain
SAMLResponse, TAI will be skipped and deferred.

[3/20/13 16:22:57:628 EDT] 00000025 ACSTrustAssoc 3   Request is scoped to this TAI.

請注意,我們找到了 LtpaToken2 cookie,而且 Fake TAI 和 SAML TAI 都未被再次調用。HitCount 應用程序被調用,它報告了調用方的身份 - 從主題獲取,主題是從第 3 條消息中的 SAML Response 生成的(清單 6)。

[3/20/13 16:22:57:632 EDT] 00000025 SystemOut     O   J2EE APIs: HitCount received
request from Alice

SAML TAI 屬性

盡管作為一個 TAI 進行實現支持將函數向後移植到更早的 WebSphere Application Server 版本中,但它導致必須正確定義許多 TAI 屬性才能讓 TAI 繼續運行(如果熟悉 WebSphere Application Server V6.1 中的 SPNEGO TAI,您應將設置 SPNEGO TAI 屬性的復雜性與 WebSphere Application Server V7.0 中的 SPNEGO Web Authenticator 中集成的等效函數進行對比,SPNEGO 配置是管理控制台中的第一個類結構。)

SAML TAI 屬性記錄在 信息中心 中。有一個屬性分層結構,請在信息中心中查閱詳細信息:

全局屬性適用於所有為 SAML TAI 配置的 SSO 合作伙伴(托管 IdP 的合作伙伴)。這些屬性沒有前綴 “sso_<id>”(其中 <id> 是一個整數)。大多數全局屬性都可使用特定的 IdP 等效屬性進行覆蓋。

服務提供程序屬性適用於某個服務提供程序,針對每個 SSO 服務提供程序合作伙伴的這些屬性分組到惟一的 sso_<id> 之下。

IdP 屬性適用於為 SAML TAI 配置的身份提供程序。要分配標識每個身份提供程序合作伙伴的惟一屬性名稱,可將一個 idp_<id> 嵌入在屬性名稱中,並使用它對於每個 SSO IdP 合作伙伴有關聯的屬性進行分組。對於某個給定的服務提供程序,配置的 IdP 屬性具有前綴 “sso_<id>.idp_<id^>”。

我們不打算解釋所有屬性的用途,而是將它們分組到一起,以展示如何應用它們來解決某些問題。(這裡並沒有解釋所有屬性。)

IdP 發起的 SSO:需要哪些屬性才能完成 SSO?

向 IdP 驗證後,IdP 將浏覽器重定向到合適的 ACS URL。SAML TAI 確定向請求應用哪種(如果有)服務提供程序配置。

為了確定應用何種配置,SAML TAI 將 URL 與所有 sso_<n>. sp.acsUrl 屬性中定義的模式相匹配。如果找到了匹配值,則應用所有 sso_<n>(服務提供程序)屬性,以及所有全局屬性。

一旦決定解釋請求,SAML TAI 需要確保 IdP 的身份是一組受信任的 IdP 之一。這裡提供了兩個選項,IdP 可通過以下兩種方式進行識別:                                

區分名 (distinguished name),sso_<n>.idp_<m>.allowedIssuerDN

簡單名稱,sso_<n>.idp_<m>.allowedIssuerName。

在用戶向 ACS URL 發出包含無效 SAML Response(或許由另一個 IdP 發出)的 POST 請求時,將通過重定向返回 sso_<n>.acsErrorPage 所指定的 URL。

了解如何從 SAML 響應提取用戶身份,如何創建用戶身份,登錄成功後重定向到何處,如何信任來自某個受信任 IdP 的請求,以及如何保護來路不正的請求之前,我們首先看看 SP 重定向到 IdP Web SSO 用例的更多屬性。

SP 重定向到 IdP Web SSO:完成 SSO 需要哪些屬性?

考慮圖 3 中所示的情形。一個 GBM 用戶在浏覽器中訪問 https://benefits-portal.uac.com/wps/myportal。如上所述,TAI 沒有立即攔截;這不是一個 ACS URL。因為這是第一個請求,所以沒有 LtpaToken2 cookie。前面已經提到過,基於傳入請求中的某些數據,SAML TAI 返回重定向到正確 IdP 的 HTTP 302 代碼。SAML TAI 如何知道將此請求重定向到(在本例中)GBM IdP 而不是其他某個 IdP?

SAML TAI 過濾器屬性 sso_<n>.sp.filter 控制了 SAML TAI 如何確定某個特定 URL 應否發起向 IdP 的服務提供程序重定向。該過濾器的功能與 SPNEGO TAI 的過濾器相同。如果缺少過濾器設置,則會攔截發送到 Java EE 保護 URL 的所有請求。

APAR PM84513 通過多種 SP 配置解決了一個問題,每種配置都有惟一的 “過濾器” 定義;發送到 SAML TAI 的第一個請求會查找匹配的 “過濾器”,以確定對第一個請求應用何種 SP 配置。如果沒有這個 APAR,那麼對 SAML TAI 的所有後續調用都將繼續使用相同的 SP 配置;後續請求不會檢查匹配的過濾器條件。強烈建議應用此修復補丁。

如果基於過濾器條件而攔截了請求,將會返回 sso_<n>.sp.login.error.page 屬性指定的頁面。如果只有一個 IdP,這可能是一個僅供此 IdP 使用的 URL。

如果有多個 IdP,那麼 SP 配置的每個 IdP 都將有自己的 sso_<n>.idp_<m>.SingleSignOnUrl 值,並指定 SAML TAI 重定向到哪個 URL 來發起 SAML SSO。但問題仍然存在:如何確定選擇哪個 “idp_<m>”?如果有多個 IdP,login.error.page 屬性可指向一個包含多個 IdP 鏈接的 HTML 頁面;在更加完善的解決方案中,該屬性指向一個實現清單 7 中所示的接口的類。

清單 7. IdentityProviderMapping 接口
import javax.servlet.http.HttpServletRequest;
import java.util.String ;
import java.util.ArrayList ;
import com.ibm.websphere.security.NotImplementedException;
import com.ibm.wsspi.security.web.saml.IdentityProviderMapping;
        
public abstract interface IdentityProviderMapping {
   public abstract String getIdentityProviderOrErrorURL(
      HttpServletRequest req,
      String errMsg, 
      String acs, 
      ArrayList<String> ssoUrls) throws NotImplementedException;
}

實現此類,將 JAR 文件放在 <WAS>/lib/ext 中。可在實現中執行任何可以想到的邏輯。在清單 8 中所示的示例源代碼 SampleIDPMapping.java 中,搜索一個 ?idp=<URL> 參數或(假設用戶之前訪問過該站點)一個名為 SAMLIDP 的持久性 cookie。

清單 8. SampleIDPMappingImpl.java 類摘錄

private static final String COOKIE = "SAMLIDP";
…
// Assumes that 
//   idp_1 is configured as GBM IdP
//   idp_2 is configured as Omicron Lumber IdP
//   idp_3 is configured as Purple Maple Syrup IdP
…
// Prefer URL parameter over cookies. So only look for cookies 
// if URL parameter not set.
String idpValue = req.getParameter("idp");
if (idpValue==null) {
   log.finer("URL Parameter was not found, so looking for IDP cookie");
   Cookie[] cookies = req.getCookies();
   if (cookies != null) {
      for (Cookie cookie : cookies) {
         if (cookie.getName().equals(COOKIE)) {
           String cookieValue = cookie.getValue();
…
         }
      }
   }
}
…
if (idpValue.equalsIgnoreCase("omicron")) { 
   // We know that ssoUrls.size() < 1 here
   log.finer("Omicron IDP requested. Returning (ssoUrls.get(1))");
   idpUrl = ssoUrls.get(1);
} else if (idpValue.equalsIgnoreCase("purple")) { 
   // We know that ssoUrls.size() < 1 here
   log.finer("Purple IDP requested. Returning (ssoUrls.get(2))");
   idpUrl = ssoUrls.get(2);
} else { 
   // otherwise return ssoURL[0] - default "gbm"
   log.fine("IDP requested " + idpValue + 
            ". Default to gbm IDP (ssoUrls.get(0))");
   idpUrl = ssoUrls.get(0);
}

在此示例中,如果 cookie 和 “idp=” 參數都未提供,默認情況下會選擇 GBM IdP。另一個實際示例將是,基於傳入的 HttpServletRequest 來確定使用哪個 IdP。我們沒有提供這個示例的代碼。SAML TAI 如何知道在登錄到 WebSphere Application Server 後重定向到何處?

在 SAML TAI 處理了在 POST 中發送給 ACS 的 SAML Response 後,而且 WebSphere Application Server 安全運行時讓用戶登錄並生成了一個 JAAS 主題後,ACS 應用程序將:

對浏覽器執行 HTTP 302 重定向,將它重定向到已登錄的登錄頁面。

向應用程序中的一個地址執行內部轉移。為了能夠使用此選項,所轉移到的 URL 所在的 Web 應用程序中必須包含 ACS URL。一般的 ACS 應用程序無法執行轉移操作。

IdP 發送的 SAML Response 可以有選擇地包含一個 URL,SP 應通過一個名為 RelayState 的 SAML 屬性重定向到該 URL。

為了支持上面的第一個選項,一般的 ACS 應用程序會使用 sso_<n>.sp.targetURL 屬性。如果 IdP 發送 RelayState,那麼默認情況下會使用第 3 個選項。要覆蓋所發送的 RelayState,可使用 sso_<n>.sp.useRelayStateForTarget 屬性。SP 發起的指定重定向目標的最常見方式是通過原始 referrer URL cookie 來完成的,該 cookie 也被稱為 WasSamlSpReqURL cookie。

SAML TAI 為什麼相信 SAML 斷言?

您可能會問上面這個問題。否則,攻擊者可能設計出一個格式正確的 SAML Response,通過 POST 發送到 ACS,然後以攻擊者想要的任何人的身份登錄。SAML TAI 必須確認請求來自一個受信任的 IdP。換言之,SAML TAI 必須向 IdP 進行驗證。這通過確認 SAML Response 的數字簽名來執行。

SAML Response 包含數據的數字簽名。該簽名包含使用 SAML Response 中通告的算法對數據計算的哈希值。這個哈希輸出隨後使用 IdP 所持有的私鑰進行加密。要驗證該簽名,SP (SAML TAI) 計算相同內容的哈希值,然後解密 IdP 提供的哈希值(SAML Response 包含公共證書)。如果它們匹配,則 SP 知道該內容未被更改(這稱為數據完整性),而且該內容是由與公共證書對應的私鑰持有者生成的。公共證書的發行者必須值得信賴。

以下屬性控制了 SAML TAI 的簽名確認行為:

sso_<n>.sp.wantAssertionsSigned

sso_<n>.sp.trustAnySigner  — 當然,此屬性要小心使用。

sso_<n>.sp.trustStore  — 這是一個 WebSphere Application Server 信任存儲庫對象的名稱,該對象包含 IdP 的簽名者證書。它不是文件的名稱,而是在管理控制台中看到的對象名稱。

sso_<n>.sp.X509PATH  — 作為使用 WebSphere 信任存儲庫對象的一種替代方法,可提供一個包含簽名證書的中間證書的文件的路徑。

sso_<n>.sp.CRLPATH  — 一個包含證書存儲庫的名稱,其中包含一個證書撤銷列表 (CRL)。

sso_<n>.sp.trustedAlias  — 如果信任存儲庫包含多個證書,而且您希望限制信任存儲庫中的哪個證書可用於驗證簽名,那麼可以使用此屬性來指定。

正確設置這些屬性並將簽名證書保存在信任存儲庫中可能很困難。有一個名為 importSAMLIdpMetadata 的 wsadmin AdminTask 可幫助您完成此工作。

保護 SAML 斷言

發現的特定於 ADFS 2.0 的問題在默認情況下,ADFS 要求所有用於加密的證書包含一個證書撤銷列表 (CRL) 端點。如果證書不包含 CRL 端點,則必須將 ADFS 配置為不需要 CRL。可使用 Set-ADFSRelyingPartyTrust cmdlet 的 EncryptionCertificateRevocationCheck 參數。ADFS 通過區分名來識別發行方;這是一個字符串。如果該區分名包含一個 StateOrProvinceName 字段,則會出現問題。Microsoft 使用了非傳統的 “S=” 形式,而在 WebSphere Application Server 中,Java 要求該字段表示為 “ST=”。由於此差別,不能使用包含 StateOfProvinceName 字段的發行方證書。

對 ACS 應用程序的 HTTP POST 請求正常情況下應通過 https 連接發送。事實上,許多 IdP 都需要通過 SSL 連接。除了 SSL 連接所提供的加密之外,可能還有一個加密 SAML Response 對象的有效負載的原因。請記住,IdP 通過用戶的浏覽器來重定向請求。通過使用浏覽器插件,用戶可查看流經浏覽器的 SAML Response(用戶不能更改內容,因為這會導致數字簽名檢查失敗,但他仍然可以看到內容)。如果您的使用情形不需要這種輔助加密,則不需要加密 SAML Response。

為了實現加密,SP (SAML TAI) 使用了它自己的私鑰/公鑰對。通過一個公共證書為 IdP 提供公鑰的副本,它使用此公共證書來加密內容。只有私鑰的持有者 (TAI) 可解密內容。支持 SAML Response 加密的屬性包括:

sso_<n>.sp.keyStore  — 這是包含您的 SP 的個人證書的 WebSphere Application Server 密鑰存儲庫對象的名稱。它不是文件的名稱,而是在管理控制台中看到的托管的對象名稱。

sso_<n>.sp.keyAlias  — 密鑰存儲庫中的密鑰的別名。

sso_<n>.sp.keyPassword  — 訪問該密鑰所需的密碼。

sso_<n>.sp.keyName  — 無需使用密鑰別名,也可指定要使用的密鑰的完整區分名。

IdP 需要收到公共證書(和任何簽名者)。再次聲明,您可以使用 wsadmin AdminTask exportSAMLSpMetadata 創建一個可由 IdP 應用程序導入的 XML 文件(依賴於您的 IdP 系統,您可能需要編輯得到的 XML,以便僅引用加密證書信息)。

如何自定義用戶身份

IdP 斷言一個使用 SAML TAI 的用戶。根據您的具體使用情形,該用戶不一定存在於 WebSphere Application Server 用戶注冊表中。我們假設該用戶是一個本地用戶或暫時的用戶(一些 WebSphere 產品,比如 IBM Business Process Manager (BPM),要求所有登錄的用戶都存在於用戶注冊表中,所以他們必須是本地用戶。)

要斷言一個本地用戶,可指定 SAML TAI 屬性 sso_<n>.sp.idMap = localRealm。對於本地用戶,SAML Response 中的 NameID 字段被設置為 JAAS Subject 中的 userid(下面將討論如何通過 userMapImpl 屬性來映射 userid)。WebSphere Application Server 將通過查詢用戶注冊表來完成該主題。

臨時用戶是被斷言為確實存在的用戶,但他們不受基礎用戶存儲庫(比如 LDAP)中任何條目的實際支持。對於臨時用戶,principalName 從屬性 sso_<n>.sp.principalName 中的屬性名獲取。

要斷言一個臨時用戶,可設置屬性 sso_<n>.sp.idMap = idAssertion。設置該屬性(而且此屬性值為默認值)時,一些 SAML TAI 屬性可准確控制哪些用戶身份已經登錄。前兩個分別標識 SAML Response 中用於填充 principalName 和 uniqueID 的元素:

sso_<n>.sp.principalName

sso_<n>.sp.uniqueId

向 userid 分配哪個域 (realm) 由以下屬性確定:

sso_<n>>.sp.realmName

sso_<n>.sp.realmNameRange

sso_<n>.sp.defaultRealm

sso_<n>.sp.useRealm

如果使用 idAssertion,並且沒有設置任何這些與域相關的屬性,那麼 SAML Response 中定義的 IssuerName 將是所使用的域名稱。

除了上述屬性之外,還有兩種建立用戶身份的混合方法。第一種混合方法使用 idMap 值 = localRealmThenAssertion。在這種模式下,將會從 SAML Response 中提取用戶身份並搜索用戶注冊表。如果在用戶注冊表中找到了該用戶,則將以 localRealm 用戶身份繼續登錄。如果未找到該用戶,那麼登錄將以 idAssertion 用戶身份繼續進行。

第二種混合方法使用 idMap 值 = idAssertionUsingGroups。這種方法使用 SAML Response 中斷言的組信息來擴充從用戶注冊表返回的 localRealm 用戶的組成員關系信息。(考慮使用來自用戶注冊表的數據來擴充臨時用戶的組成員關系信息是沒有任何意義的,因為根據定義,臨時用戶不存在於用戶注冊表中,而且沒有額外的組要添加。)

如果從 SAML Response 考慮組成員關系,SAML Response 中的組元素的名稱由 sso_<n>.sp.groupName 屬性指定。

從 SAML Response 獲取的組成員關系可通過設置 sso_<n>.sp.groupMap=localRealm 屬性來映射到用戶注冊表組。組成員關系也可通過設置 sso_<n>.sp.groupMap= AddGroupsFromLocalRealm 在用戶的主題中斷言,甚至在用戶注冊表中不存在組時也可以這樣做。

考慮圖 6 中的示例。無需斷言用戶是否存在於 UAC LDAP (localRealm) 中,Purple 用戶是臨時用戶。它們的組成員關系也通過 SAML Response 斷言。具體來講,我們關注的是它們在 UACGroup 中的成員關系。其他組也會斷言,但對 UAC 應用程序並不重要。用戶訪問的 UAC Web 應用程序有一個安全角色,該角色被明確限定為來自外部受信任域 idp.purple.com/adfs/services/trust 的 UACGroup 組。您必須將 IdP 配置為在 SAML Response 中生成合適的組成員關系聲明。

圖 6. 斷言臨時身份

最後,SAML Response 中斷言的 userid/principalName/NameID 通常需要進行某種轉換,隨後才能向 WebSphere Application Server 斷言身份。或者 SAML Response XML 文檔(包含應使用的身份)中或許有不同的元素。sso_<n>.sp.userMapImpl 提供了 SAML TAI 的另一個插入點(一個接口),您可在其中實現一個自定義的用戶映射類來返回所斷言的用戶身份。userMapImpl 的接口如清單 9 所示。

清單 9. UserMapping 接口
import java.util.String ;
import com.ibm.websphere.security.NotImplementedException;
import com.ibm.websphere.security.UserMappingException;
import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
import com.ibm.wsspi.security.web.saml.UserMapping;
    
public abstract interface UserMapping {
      
 public abstract String mapSAMLAssertionToName(SAMLToken samlToken)
            throws UserMappingException, NotImplementedException;
}

在第二個自定義實現示例中,您希望忽略 SAML Response 中的 NameID 元素,從 Response 中的區分名元素來建立用戶身份(清單 10)。

清單 10. SampleUserMapping.java 類的摘錄片段
/** Standard ADFS name for a SAML attribute containing the DN. */
public static final String SAML_ATTR_DN = 
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/distinguishedname";
public static final String FRIENDLYNAME = "Custom User Mapping";
    
public String mapSAMLAssertionToName(SAMLToken samlToken)
            throws UserMappingException, NotImplementedException {
   log.entering(CLASSNAME, "mapSAMLAssertionToName");
   String result = null;
   result = getDN(samlToken);
   log.fine(FRIENDLYNAME + " mapped to user " + result);
   log.exiting(CLASSNAME, "mapSAMLAssertionToName");
   return result;
}
    
public static String getDN(SAMLToken token) throws UserMappingException {
   String dn = null;
   if (token != null) {
      List<SAMLAttribute< attrList =  token.getSAMLAttributes();
      if (attrList != null  && attrList.size() < 0) {
         for (SAMLAttribute attr : attrList) {
            if (attr.getName().equals(SAML_ATTR_DN)) {
               if (attr.getStringAttributeValue().length > 0) {
                  dn = attr.getStringAttributeValue()[0];
                  log.fine("User Mapping found DN: " + dn);
                  break;
               }
            }
    …// Error checking code removed.
   return dn;
}

設置 SAML TAI

下面通過一些高級架構類型問題的形式,幫助您了解設置 SAML TAI 的總體步驟:

SAML TAI 要保護哪些 URL? – 您需要確定哪些 URL(應用程序,如果有)將導致 SP 重定向到 IdP Web SSO 情形。這將是過濾器屬性的輸入。

對於 SP,IdP 將重定向到哪個 ACS URL?

用戶將以 localRealm 還是 idAssertion userid 登錄?

SAML Response 是否會加密?

對於每個 IdP,您需要知道:

IdP 供應商是誰?

該供應商是否支持 RelayState?

IdP 接受何種格式的 SP 元數據?

IdP 身份 ID 是什麼?

您是否擁有 IdP 所使用的簽名證書,包括完整的發行者鏈?

籠統地講,WebSphere Application Server 管理步驟包括:

如果加密 SAML Response,則使用 WebSphere Application Server 管理工具創建一個新的密鑰存儲庫,稱為(舉例而言)SPKeyStore:                            生成私鑰/公鑰和公共證書。導出公共證書,可能以 SAML 元數據形式。

使用管理工具,創建一個名為(舉例而言)IdPTrustStore 的新的信任存儲庫。安裝簽名 IdP 簽名證書和證書鏈。

添加 SAML TAI (ACSTrustAssociationInterceptor) – 還不要啟用 TAI。

將 TAI 添加到 com.ibm.websphere.security.DeferTAItoSSO 自定義屬性(以啟用 SP 重定向到 IdP Web SSO)。

將 TAI 添加到 com.ibm.websphere.security.InvokeTAIbeforeSSO 自定義屬性(以首選 SAML 令牌而不是 LtpaToken)。

配置 SAML TAI 屬性。

安裝 ACS 應用程序:<was>/installableApps/WebSphereSamlSP.ear。

啟用 TAI。

一些與 SAML TAI 相關的有用的 AdminTask 包括:

AdminTask.showSAMLTAISSO()

AdminTask.showSAMLIdpPartner()

AdminTask.importSAMLIdpMetadata()

AdminTask.exportSAMLSpMetadata()

有用的軌跡規范:

com.ibm.ws.security.web.saml.*

com.ibm.ws.security.*

提示和技巧

不要將浏覽器直接指向 ACS URL,除非發出了一個 SAML Response 供它處理。否則,您會遇到針對該應用程序的身份驗證質詢。對於發布的 ACS,這是一個 Basic Auth 質詢。如果實現了自己的自定義 ACS 應用程序,那麼這可能是一種基於表單的登錄。

如果編寫自己的 UserMapping 或 IdPMapping 類,如上面的代碼示例中所示,那麼可以使用 Java 日志將此代碼與 WebSphere Application Server 軌跡基礎架構相集成。這使您能夠在代碼中動態地啟用或禁用追蹤。

結束語

本文提供了一些指導信息,幫助運行在 IBM WebSphere Application Server 之上的那些系統的管理員了解新的 SAML Web TAI,了解它在 WebSphere Application Server 中的現有 Web 安全運行時內的工作原理,它如何讓安全性產生細微的變化,大量自定義 TAI 屬性如何彼此交互,以及何時使用這些自定義 TAI 屬性(以及何時不需要它們)。我們還提供了兩個樣例實現,展示了如何自定義登錄流程。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved