日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

构建自定义安全令牌服务

發(fā)布時間:2024/3/13 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 构建自定义安全令牌服务 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

[轉(zhuǎn):http://msdn.microsoft.com/zh-cn/magazine/dd347547.aspx]

本文基于 "Geneva" 框架的預發(fā)布版本撰寫而成。所有信息均有可能發(fā)生變更。

本文將介紹以下內(nèi)容:

  • 使用 Geneva 框架實現(xiàn)安全令牌服務
  • 聯(lián)合安全性
  • 聲明轉(zhuǎn)換

本文使用了以下技術(shù):
Windows Communication Foundation、ASP.NET、Geneva 框架

代碼下載位置:MSDN 代碼庫
在線瀏覽代碼

? 目錄

安全令牌服務入門
構(gòu)建自定義主動 STS
擴展 SecurityTokenService
托管和配置 STS
安全令牌處理程序
構(gòu)建自定義被動 STS
FederatedPassiveTokenService 控件
SessionAuthenticationModule
用戶身份驗證
聲明轉(zhuǎn)換
總結(jié)

Microsoft 基于聲明的訪問 (CBA) 平臺戰(zhàn)略(代號為 "Geneva")包括 "Geneva" 框架、"Geneva" 服務器和 Windows CardSpace "Geneva"。Geneva 框架可為開發(fā)人員提供相關(guān)工具來構(gòu)建基于聲明的應用程序和服務(這些服務包括由“安全令牌服務”(STS) 所頒發(fā)的令牌),還提供相關(guān)工具來構(gòu)建自定義 STS 和啟用 CardSpace 的 Windows 應用程序。雖然 Geneva 服務器是企業(yè)級 STS,但 Geneva 框架可以為不需要企業(yè)級功能的環(huán)境構(gòu)建自定義 STS。Windows CardSpace Geneva 由 Windows 客戶端計算機中作為標識選擇器和標識提供者的 Windows CardSpace 演變而來。

在我上一篇介紹 Geneva 框架的文章中,我曾討論過依靠 STS 頒發(fā)的令牌來構(gòu)建基于聲明的 Windows Communication Foundation (WCF) 服務的一種較好方法。在這里,我將使用 Geneva 框架來構(gòu)建自定義 STS。

在繼續(xù)閱讀本文之前,建議您先閱讀一下由 Keith Brown 和 Sesha Mani 合著的Geneva 框架開發(fā)人員白皮書和我的上一篇文章“Geneva 框架構(gòu)建基于聲明的 WCF 服務的更好方法”。

安全令牌服務入門

無論是基于 Geneva 服務器的 STS 還是使用 Geneva 框架構(gòu)建的 STS,其主要作用都是作為安全網(wǎng)關(guān)對調(diào)用方進行身份驗證,并頒發(fā)附帶描述調(diào)用方聲明的安全令牌。從前面提到的文章中,您應該能夠回想起 STS 身份驗證支持多種方案:

  • 從身份驗證機制中分離出應用程序和服務,從而使其能夠?qū)W⒂谑跈?quán)相關(guān)聲明。
  • 支持多種憑據(jù)類型,而不會使應用程序和服務的實現(xiàn)變復雜。
  • 支持聯(lián)合方案,用戶可以通過在自身的域中進行身份驗證來獲得對另一個域中資源的訪問權(quán)限(通過建立不同域的 STS 之間的信任關(guān)系)。
  • 簡化標識委派方案,經(jīng)過身份驗證的用戶將獲得對下游服務的訪問權(quán)限。
  • 簡化聲明轉(zhuǎn)換,使相關(guān)聲明能夠用于對應用程序和服務進行授權(quán)。

其中的任何方案都可以基于被動聯(lián)合(基于瀏覽器)或主動聯(lián)合(基于 Windows 客戶端)。下面我將詳細介紹這些方案,同時說明如何使用 Geneva 框架在自定義 STS 中構(gòu)建相關(guān)邏輯。

在深入探討 STS 的實現(xiàn)之前,讓我們先來回顧一些基礎知識。在主動聯(lián)合中使用的 STS 是 WS-Federation 主動請求者配置文件(請參閱 WS-Federation TC)和(主要)WS-Trust 規(guī)范(請參閱 WS-Trust 1.3)的實現(xiàn)。

從較高層次看,WS-Trust 使用四種服務操作來描述一個約定:頒發(fā)、驗證、續(xù)訂和取消。客戶端分別調(diào)用這些操作來請求安全令牌、驗證安全令牌、續(xù)訂已過期的安全令牌以及取消不應再繼續(xù)使用的安全令牌。根據(jù) WS-Trust 規(guī)范,每個操作都必須以“請求安全令牌”(RST) 的格式發(fā)送消息,并以“RST 響應”(RSTR) 的格式返回消息。在本文中,我假定頒發(fā)的令牌是“安全聲明標記語言”(SAML) 1.1 或 SAML 2.0 令牌。

圖 1 展示了主動令牌頒發(fā)時 RST 和 RSTR 的核心內(nèi)容。RST 消息包括請求安全令牌所需的必要信息,其中涉及待頒發(fā)令牌的類型(在本討論中是 SAML)、將要被納入到頒發(fā)令牌中的“依賴方”(RP) 所請求的聲明、有關(guān) RP (AppliesTo) 的信息(包括 URL 和通常用于標識 RP 的證書)以及將被用于 RSTR 所返回的“證明密鑰”(proof key) 的可選(未顯示)密鑰材料。

圖 1 主動聯(lián)合方案的令牌頒發(fā)

如果令牌頒發(fā)成功,RSTR 將包括頒發(fā)的 SAML 令牌和證明密鑰(假定 STS 決定使用哪個證明密鑰,因此必須在 RSTR 中返回它)。SAML 令牌將包括已驗證方的相關(guān)聲明,它由 STS 簽名來保護令牌不被篡改,令牌中將包含用于 RP 加密的證明密鑰,并且它會為 RP 加密自身以確保只有目標接收節(jié)點才能處理該令牌。

客戶端使用證明密鑰來簽署發(fā)往 RP 的消息。RP 必須能夠在 SAML 令牌中解密證明密鑰,否則拒收該消息。如果令牌中的證明密鑰與消息中的簽名匹配,則證明此次對 RP 的調(diào)用是由請求該令牌的調(diào)用方所發(fā)送的。

被動聯(lián)合方案基于 WS-Federation 被動請求者配置文件,其中涉及基于瀏覽器的通信。雖然底層消息傳遞仍基于 WS-Trust,但 RST 卻在 STS URL 中被分解為查詢字符串參數(shù),而 RSTR 通常會作為表單參數(shù)被發(fā)布到 RP。被動 STS 和 RP 使用聯(lián)合 Web 處理程序來截取這些參數(shù)。被動 STS 可以直接處理 WS-Trust 請求,或者將其傳遞到底層 WS-Trust 實現(xiàn)。圖 2 說明了在被動聯(lián)合方案中對 RST 和 RSTR 的處理方式。

圖 2 被動聯(lián)合方案的令牌頒發(fā)

主動與被動聯(lián)合方案的一個本質(zhì)差異在于頒發(fā)的 SAML 令牌的類型。主動聯(lián)合通常依靠使用“密鑰所有者”(holder-of-key) 類型主體確認的 SAML 令牌,這意味著正如我前面所述,在實際當中存在著一個證明密鑰,它可以證明發(fā)出令牌進行驗證的客戶端是請求該令牌(也稱為 ActAs 行為)的主體。被動聯(lián)合方案通常涉及帶有“持有者”(bearer) 類型主體確認的 SAML 令牌(也稱為持有者令牌)。這種類型的令牌不包含證明密鑰,有時也稱為無密鑰令牌。它依靠傳輸來確保從 STS 獲得該令牌并將其傳遞給 RP。

這些概念(WS-Federation、WS-Trust 和 SAML 令牌)是下面要討論的主題的重要背景信息。首先,我將說明如何使用 Geneva 框架來構(gòu)建主動 STS。然后,我將討論如何構(gòu)建被動 STS,最后會介紹一些它們各自的擴展方案。

構(gòu)建自定義主動 STS

在簡單的主動聯(lián)合方案中(如圖 3 所示),通常存在以下參與者:

  • RP,由客戶端調(diào)用的服務。
  • 單獨的 STS(也作為服務實現(xiàn)),支持 WS-Trust 協(xié)議。此 STS 將對調(diào)用方進行身份驗證并頒發(fā)具有標識調(diào)用方聲明的安全令牌,也稱為標識提供者或 IP-STS。
  • 客戶端,在本例中為基于 Windows 的應用程序,它依靠代理對 STS 進行身份驗證、檢索令牌頒發(fā)結(jié)果以及發(fā)送消息給 RP(它會提供用于身份驗證和授權(quán)的頒發(fā)令牌)。

圖 3 使用單一 RP 和主動 IP-STS 的簡單聯(lián)合方案

圖 4 說明了在此實現(xiàn)中可以靈活設置的部分。其中包括自定義 SecurityTokenService 實現(xiàn)、使用 ServiceHost 擴展 (WSTrustServiceHost) 初始化用于聯(lián)合的運行時、使用 WSTrustContract 類型的派生配置一個或多個 WS-Trust 端點以及用于標識模型運行時的其他相關(guān)配置設置。在接下來的章節(jié)中,我將回顧基于 Geneva 框架的自定義 STS 實現(xiàn)中的各個要素。

圖 4 自定義主動 STS 和主動 IP-STS 的實現(xiàn)體系結(jié)構(gòu)

擴展 SecurityTokenService

Geneva 框架通過 Microsoft.IdentityModel.SecurityTokenService 命名空間中的 SecurityTokenService 類型為構(gòu)建自定義 STS 提供核心功能。此抽象類擔負著傳遞 RST 和 RSTR 消息和生成安全令牌的重任。自定義 STS 類型將繼承該類并提供(至少)以下功能:

  • 構(gòu)造函數(shù),用于接受自定義 SecurityTokenServiceConfiguration 實例以配置 STS 的一些基本功能(稍后討論)。
  • GetScope 的重載函數(shù),用于驗證請求的目標 RP,并為該 RP 提供正確的加密憑據(jù)和用于安全令牌的簽名憑據(jù)。
  • GetOutputClaimsIdentity 的重載函數(shù),用于為生成的安全令牌提供聲明。

圖 5 顯示了使用此功能實現(xiàn)的簡單自定義 STS 的部分代碼。請回想一下在圖 1 和圖 2 中介紹過的主動 STS 通信流程。STS 的實現(xiàn) IdentitySTS 將在調(diào)用 GetScope 時驗證傳入 RST——通過驗證 RST 的 AppliesTo 元素是否確實指向信任的 URI。假定 STS 管理著一組可為其頒發(fā)令牌的可信 RP 及其證書。如果 AppliesTo 通過了驗證,GetScope 將把該范圍的 EncryptingCredentials 屬性設置為正確的證書,在本例中為 "RPKey"。此外,SigningCredentials 屬性也將被設置為正確的證書,此證書將被用于為頒發(fā)的令牌簽名。通常情況下,它是 STS 的私鑰,在本例中為 "IPKey"。

? 圖 5 簡單的自定義 STS 實現(xiàn)

public class IdentitySTS : SecurityTokenService {public IdentitySTS(SecurityTokenServiceConfiguration config): base( config ){}protected override IClaimsIdentity GetOutputClaimsIdentity(IClaimsPrincipal principal, RequestSecurityToken request, Scope scope){IClaimsIdentity claimsIdentity = new ClaimsIdentity();claimsIdentity.Claims.Add(new Claim(ClaimTypes.Name, principal.Identity.Name));claimsIdentity.Claims.Add(new Claim(ClaimTypes.Role, "Users"));return claimsIdentity;}protected override Scope GetScope(Microsoft.IdentityModel.Claims.IClaimsPrincipal principal, RequestSecurityToken request){Scope scope = new Scope(request);scope.EncryptingCredentials = this.GetCredentialsForAppliesTo(request.AppliesTo);scope.SigningCredentials = new X509SigningCredentials(CertificateUtil.GetCertificate(StoreName.My, StoreLocation.LocalMachine, "CN=IPKey"));return scope;}private X509EncryptingCredentials GetCredentialsForAppliesTo(EndpointAddress appliesTo){if (appliesTo == null || appliesTo.Uri ==null || string.IsNullOrEmpty(appliesTo.Uri.AbsolutePath)){throw new InvalidRequestException("AppliesTo must be supplied in the RST.");}X509EncryptingCredentials creds = null;if (appliesTo.Uri.AbsoluteUri.StartsWith("http://localhost:8000/RelyingPartyService")){creds = new X509EncryptingCredentials(CertificateUtil.GetCertificate(StoreName.TrustedPeople, StoreLocation.LocalMachine, "CN=RPKey"));}elsethrow new InvalidRequestException(String.Format("Invalid relying party address: {0}", appliesTo.Uri.AbsoluteUri));return creds;} }

當調(diào)用 GetOutputClaimsIdentity 時,運行時將傳遞 ClaimsPrincipal 及經(jīng)過驗證的調(diào)用方標識。此標識通常用于決定要授予調(diào)用方的適當聲明。在圖 5 中,代碼將為調(diào)用方生成一個名稱聲明和硬編碼的角色聲明,并會以 ClaimsIdentity 的形式返回。此 ClaimsIdentity 將向運行時提供待頒發(fā)令牌的聲明。

此 STS 實現(xiàn)還可以針對以下功能進行擴展:

  • GetOutputClaimsIdentity 可以包括用于在自定義憑據(jù)存儲庫中查找用戶及查找其他聲明的代碼。例如,角色列表、有關(guān)用戶的其他相關(guān)詳細信息(如電子郵件地址),或者代表更精細應用程序權(quán)限(如創(chuàng)建、讀取、更新或刪除)的自定義聲明。
  • GetScope 可以在列出所有可信 RP 及其關(guān)聯(lián)證書的自定義數(shù)據(jù)庫中查找 AppliesTo URI。

托管和配置 STS

如果熟悉 WCF,那您一定清楚必須配置一個或多個端點才能使客戶端將消息發(fā)送到某個服務。對于 STS 而言,將要用于各個端點的服務約定必須基于 WS-Trust 協(xié)議,其中包括四個操作:頒發(fā)、驗證、續(xù)訂和取消。事實上,STS 能夠?qū)崿F(xiàn)兩個版本的 WS-Trust 協(xié)議:

  • WS-Trust 1.3:最新版本的 WS-Trust 規(guī)范。
  • WS-Trust 2005 年 2 月:許多行業(yè)合作伙伴在等待標準通過認可期間實施的 WS-Trust 版本。

您還可以在 SecurityTokenService 類型中提供 GetScope()、GetOutputClaimsIdentity() 等方法的異步實現(xiàn)。這將提高 I/O 密集型操作(如訪問證書或與聲明數(shù)據(jù)交互)的可伸縮性。為 STS 配置端點時,必須選擇要為端點公開的約定。Microsoft.IdentityModel.Protocols 命名空間包括兩個用于 STS 端點的服務約定:IWSTrust13SyncContract 和 IWSTrustFeb2005SyncContract。圖 6 顯示了具有兩個端點的 STS 服務配置,每個端點都有一個約定。請注意還有用于實現(xiàn)異步代理的異步版本的約定:IWSTrust13AsyncContract 和 IWSTrustFeb2005AsyncContract。

? 圖 6 具有多個 WS-Trust 端點的 STS 服務配置

<service name="Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract" behaviorConfiguration="stsBehavior"><endpoint address="WSTrustFeb05" binding="wsHttpBinding" contract="Microsoft.IdentityModel.Protocols.WSTrust.IWSTrustFeb2005SyncContract"/><endpoint address="WSTrust13" binding="wsHttpBinding" contract="Microsoft.IdentityModel.Protocols.WSTrust.IWSTrust13SyncContract"/> </service>

STS 應該基于 WS-Trust 2005 年 2 月的版本公開端點,以便向后兼容早期的客戶端。實現(xiàn)這兩種約定的服務類型是 Microsoft.IdentityModel.Protocols.WSTrust 命名空間中的 WSTrustServiceContract 類型。這是一個應在 STS 的 <service> 配置部分引用的類型。

圖 4 中的圖表所示,<service> 配置及其端點被用來使用正確的 WSTrustServiceContract 類型初始化主機。在主機初始化期間,還會使用對自定義 SecurityTokenService 實現(xiàn)的引用來初始化此類型。這就是運行時直接將消息傳遞到自定義 STS 的方式。

圖 6 中,兩個 STS 端點都依賴于 Windows 憑據(jù)來驗證調(diào)用方(wsHttpBinding 的默認行為)。STS 可以使用其他綁定配置來公開多個端點,以便支持不同的憑據(jù)類型。這還包括為每種憑據(jù)類型配置正確的安全令牌處理程序。稍后我將討論令牌處理程序的配置設置。

Geneva 框架將提供用于托管 STS 實例的自定義 ServiceHost 類型 WSTrustServiceHost。下面的代碼說明了如何在自托管環(huán)境中構(gòu)造 WSTrustServiceHost 類型:

WSTrustServiceHost stsHost = new WSTrustServiceHost(new IdentitySTSConfiguration()); stsHost.Open();

WSTrustServiceHost 依賴自定義 SecurityTokenServiceConfiguration 實例來初始化 WS-Trust 端點的運行時、啟用 STS 的元數(shù)據(jù)交換行為以及配置元數(shù)據(jù)交換端點。

在 IIS 中托管時,WSTrustServiceHostFactory 類型用于存檔相同的結(jié)果。在 .svc 文件中,@ServiceHost 配置將指定工廠類型和自定義 SecurityTokenServiceConfiguration 類型,如下所示:

<%@ ServiceHost Factory="Microsoft.IdentityModel.Protocols.WSTrust. WSTrustServiceHostFactory" Service="STS.IdentitySTSConfiguration" %>

工廠在激活后將使用指定的配置來初始化 WSTrustServiceHost。

為 STS 初始化 WSTrustServiceHost 時,必須使用自定義的 SecurityTokenServiceConfiguration 類型。圖 7顯示了名為 IdentitySTSConfiguration 的自定義實現(xiàn)。

? 圖 7 自定義 SecurityTokenServiceConfiguration

public class IdentitySTSConfiguration: SecurityTokenServiceConfiguration {public IdentitySTSConfiguration(): base("http://localhost:8010/sts"){this.TokenIssuerName = "http://localhost:8010/sts";this.SigningCredentials = new X509SigningCredentials(CertificateUtil.GetCertificate(StoreName.My, StoreLocation.LocalMachine, "CN=IPKey"));this.SecurityTokenService = typeof( IdentitySTS);}}

此類型必須為 STS 提供一個 URI、簽名的憑據(jù)以及對與該配置相關(guān)聯(lián)的 STS 類型的引用。在 STS 頒發(fā)托管卡時,URL 必須有效,否則 Windows CardSpace 將無法導入這些卡。基類型要求為 TokenIssuerName 的構(gòu)造函數(shù)傳入一個字符串值,但我建議在代碼中重載它,以便能夠從配置中動態(tài)設置 URI,而不是硬編碼這個需要傳入構(gòu)造函數(shù)的值。

SecurityTokenServiceConfiguration 類型也公開了一些屬性,它們可以用于設置密鑰大小和令牌類型的默認值、禁用對元數(shù)據(jù)的訪問、控制令牌生存期和時鐘偏差、設置自定義 RST 和 RSTR 序列化程序、配置用來驗證調(diào)用方的令牌處理程序以及配置 WS-Trust 端點。

下面的示例顯示了如何禁用元數(shù)據(jù)訪問以及如何通過編程方式而不是依賴 <service> 配置設置來初始化 WS-Trust 端點(類似于圖 6 中所示):

IdentitySTSConfiguration config = new IdentitySTSConfiguration(); config.DisableWsdl = true; config.TrustEndpoints.Add(new ServiceHostEndpointConfiguration("WSTrustFeb05", new WSHttpBinding(), typeof(IWSTrustFeb2005SyncContract))); config.TrustEndpoints.Add(new ServiceHostEndpointConfiguration("WSTrust13", new WSHttpBinding(), typeof(IWSTrust13SyncContract)));WSTrustServiceHost stsHost = new WSTrustServiceHost(config);

基本 SecurityTokenServiceConfiguration 類型還通過讀取 <microsoft.identityModel> 配置部分來初始化相關(guān)的 STS 配置設置。能夠為自定義 STS 進行聲明性配置的設置包括最大時鐘偏差、用于身份驗證和頒發(fā)的安全令牌處理程序、聲明驗證管理器、頒發(fā)者名稱注冊以及令牌解析程序。圖 8 顯示了一些為 STS 配置的有用設置。

? 圖 8 STS 的 配置

<microsoft.identityModel><maximumClockSkew value="00:05:00"/><claimsAuthenticationManager type="STS.CustomClaimsAuthenticationManager, STS"/><securityTokenHandlers><remove type="Microsoft.IdentityModel.Tokens.WindowsUserNameSecurityTokenHandler, Microsoft.IdentityModel, Version=0.5.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /><add type="Microsoft.IdentityModel.Tokens.MembershipUserNameSecurityTokenHandler, Microsoft.IdentityModel, Version=0.5.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"><usernameSecurityTokenHandlerRequirement membershipProvider="CustomProviders.CustomMembershipProvider, CustomProviders, Version=1.0.0.0, Culture=neutral,PublicKeyToken=c03h5a64f15d0b3f" /></add></securityTokenHandlers> </microsoft.identityModel>

對于非 Windows 憑據(jù),會調(diào)用一種自定義的 ClaimsAuthenticationManager 類型,它可以在 GetOutputClaimsIdentity 中頒發(fā)聲明之前向運行時提供自定義 ClaimsPrincipal 類型。自定義安全令牌處理程序可能被配置為提供一些設置來覆蓋特定處理程序的默認行為,或更改特定憑據(jù)類型的安全令牌處理程序的選項。

安全令牌處理程序

您可能需要一種服務行為配置來確定為每個 STS 端點進行身份驗證和授權(quán)時所采用的方式。請回想一下,我在上一篇文章中曾講過 Geneva 框架處理事情的方式略有不同。對于身份驗證來說,<securityTokenHandlers> 集合將指定可用于驗證傳入請求的 SecurityTokenHandler 類型。

此集合只能為每個 SecurityTokenHandler 類型包含一個項目。例如,只能為各憑據(jù)類型注冊一個 KerberosSecurityTokenHandler、UserNameSecurityTokenHandler、X509SecurityTokenHandler、Saml11SecurityTokenHandler 或 Saml2SecurityTokenHandler 來處理請求。如果 STS 端點需要 UserName 憑據(jù),則默認注冊的 UserNameSecurityTokenHandler 是 WindowsUserNameSecurityTokenHandler。圖 8說明了如何刪除 WindowsUserNameSecurityTokenHandler 并添加 MembershipUserNameSecurityTokenHandler 作為其替換處理程序——包括與成員關(guān)系提供者相關(guān)的配置設置。

您還可以創(chuàng)建自定義 SecurityTokenHandler 類型。請記住,只要它們是從與令牌類別(例如 UserNameSecurityTokenHandler)匹配的相應基類派生而來的,那么您就可以使用新的自定義處理程序來替換默認處理程序。圖 9 說明了名為 CustomUserNameSecurityTokenHandler 的自定義 UserNameSecurityTokenHandler 實現(xiàn)。

? 圖 9 自定義 UserNameSecurityTokenHandler

public class CustomUserNameSecurityTokenHandler: UserNameSecurityTokenHandler {public override ClaimsIdentityCollection ValidateToken(SecurityToken token){UserNameSecurityToken userNameToken = token as UserNameSecurityToken;AuthenticateUser(userNameToken.UserName, userNameToken.Password);return new ClaimsIdentityCollection(new IClaimsIdentity[] {new ClaimsIdentity(new Claim(System.IdentityModel.Claims.ClaimTypes.Name,userNameToken.UserName), "CustomUserNameSecurityTokenHandler")});}public override bool CanValidateToken{get { return true; }} }

至少,必須在自定義 SecurityTokenHandler 實現(xiàn)中重載 ValidateToken 和 CanValidateToken。在 ValidateToken 內(nèi)部,您要負責根據(jù)相應的憑據(jù)存儲庫來驗證身份。該驗證的結(jié)果應該是一組聲明,此聲明可被返回給運行時以便附加到請求線程的 ClaimsPrincipal。

圖 10 使用單一 RP 和被動 IP-STS 的簡單聯(lián)合方案

重載 CanValidateToken 并返回 True 也非常重要。如果沒有這一重載,令牌處理程序?qū)o法注冊到集合中,從而無法被調(diào)用。

構(gòu)建自定義被動 STS

在簡單的被動聯(lián)合方案中,也存在著與主動聯(lián)合方案同樣的參與者(如圖 3 所示),不同之處在于其客戶端是瀏覽器而 RP 是 Web 應用程序,另外 IP-STS 還需要作為 Web 應用程序的前端以處理基于 HTTP 的通信。圖 10 說明了被動聯(lián)合的參與者和通信流。

對于核心 STS 而言,此方案中可以靈活設置的部分與圖 4 中所示的內(nèi)容相似,但在被動 STS 對身份驗證的處理方式和對底層 STS 功能的調(diào)用方式方面也存在著明顯的差異。圖 10 中的圖表從較高級別說明了這些不同之處。被動 STS 是作為網(wǎng)站來實現(xiàn),它需要 SSL 加密以確保令牌頒發(fā)過程的安全。默認頁面 (Default.aspx) 承載了一個通過底層自定義 STS 來促進通信的控件,它的配置過程與主動 STS 一樣。

STS 站點必須在令牌頒發(fā)之前驗證調(diào)用方,而這正是傳統(tǒng)的 ASP.NET 配置執(zhí)行其驗證和授權(quán)功能的地方。在圖 11 中,STS 應用程序被配置為用于窗體身份驗證,因此如果請求尚未經(jīng)過 FormsAuthenticationModule 的驗證,則它們將被重定向到登錄頁面 (Login.aspx)。

只需進行一個細微的改動,被動 STS 就可以與主動 STS 共享相同的核心 STS 實現(xiàn)。在 GetScope 重載函數(shù)中(如圖 5 所示),被動 STS 必須設置 ReplyToAddress 屬性,只有這樣 STS 才能在頒發(fā)令牌后重定向。這通常設置為 RP 的默認頁面(根據(jù)隨 RST 提供的 AppliesTo 地址而定):

Scope scope = new Scope(request); scope.ReplyToAddress = scope.AppliesToAddress + "/default.aspx"; // other scope settings

圖 11 使用窗體身份驗證的被動 STS 的實現(xiàn)體系結(jié)構(gòu)

被動 STS 的 Geneva 框架配置與主動 STS 并無二致。SecurityTokenServiceConfiguration 類型被用于初始化 STS(如圖 7 所示),另外還需要考慮 <microsoft.identityModel> 配置部分中的所有相關(guān)設置。

FederatedPassiveTokenService 控件

Geneva 框架提供了一個實現(xiàn)被動 STS 必要功能的控件。具體來說,它可以處理登錄和注銷 HTTP 請求,并可以將每個請求轉(zhuǎn)換到 RST 然后再調(diào)用底層 STS 實現(xiàn)。此控件還處理 RSTR 響應和 RP 重定向,并為經(jīng)過驗證的調(diào)用方編寫會話 cookie。

請按照如下方式將此控件放在被動 STS 站點的默認頁面并將其 Service 屬性設置為自定義 SecurityTokenServiceConfiguration 實現(xiàn):

<idfx:FederatedPassiveTokenService ID="FederatedPassiveTokenService1" runat="server" Service="STS.IdentityProviderSTSConfiguration, STS"> </idfx:FederatedPassiveTokenService>

此控件要求用戶必須經(jīng)過身份驗證,它會在其 PreRender 事件中對此進行檢查。需要對 STS 站點進行適當配置以確保在用戶到達此默認頁面之前將其重定向到其他頁面進行身份驗證。

只要經(jīng)過身份驗證的用戶始終定向到此默認頁面,則無需其他配置即可處理請求。此控件還提供 Error、PreSignInRequested、PostSignInRequested、PreSignOutRequested 和 PostSignOutRequested 事件來處理異常以及掛接登錄和注銷請求。

SessionAuthenticationModule

作為 FederatedPassiveTokenService 控件的替代方法,您可以通過編程方式啟用被動 STS 功能。首先在 <microsoft.identityModel> 配置部分啟用聯(lián)合驗證:

<microsoft.identityModel><federatedAuthentication enabled="true"/> </microsoft.identityModel>

然后,為被動 STS 啟用聯(lián)合模塊,即來自 Microsoft.IdentityModel.Web 命名空間的 SessionAuthenticationModule 模塊:

<modules><add name="SessionAuthentication" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule,Microsoft.IdentityModel, Version=0.5.1.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> </modules>

這將得到與 FederatedPassiveTokenService 控件相同的結(jié)果,請求將被發(fā)送到 STS 網(wǎng)站中的任意頁面。該模塊將把未驗證的調(diào)用方重定向到登錄頁面。成功登錄后,調(diào)用方將被重定向到最初請求的 STS 頁面。這種編程方法為開發(fā)人員提供了除 FederatedPassiveTokenService 控件以外的其他控件。例如,該模塊公開了以下事件以便與初始化、安全令牌管理、登錄和注銷進行交互:ConfigurationLoading、ConfigurationLoaded、SecurityTokenReceived、SecurityTokenValidated、SessionSecurityTokenCreated、SessionSecurityTokenReceived、SignedIn、SigningOut、SignedOut、SignInError 和 SignOutError。

用戶身份驗證

STS 站點負責根據(jù)支持的憑據(jù)類型來驗證用戶。雖然使用 WCF 實現(xiàn)的主動 STS 能夠輕松配置多個端點來支持不同的身份驗證機制,但被動 STS 只能支持 ASP.NET 網(wǎng)站本身配置的一種身份驗證機制。因此,必須為每種支持的身份驗證機制提供不同的被動 STS 站點。當然,這些站點都可以共享相同的核心 STS 實現(xiàn)。

被動 STS 身份驗證基于 ASP.NET 配置技術(shù)。典型選項是 Windows 身份驗證、窗體身份驗證和 Windows CardSpace 身份驗證。對于 Windows 身份驗證,將使用以下配置:

<authentication mode="Windows"/> <authorization><deny users="?"/> </authorization>

在用戶到達 STS 默認頁面前,會通過交互式對話框?qū)ζ溥M行身份驗證,因此在這種情況下不需要自定義登錄頁面。

圖 11 說明了使用窗體身份驗證的示例。FormsAuthenticationModule 將未驗證的調(diào)用重定向到登錄頁面,在這里用戶可以提供憑據(jù)。通過驗證后,登錄頁面將重定向到默認 STS 頁面,在這里聯(lián)合控件將繼續(xù)處理最初的請求。對應的 ASP.NET 配置如下:

<authentication mode="Forms"/> <authorization><deny users="?"/> </authorization>

對于 Windows CardSpace 身份驗證,可以將 STS 站點配置為窗體身份驗證,但登錄頁面將包括一個 InformationCard 控件用于 Windows CardSpace 身份驗證。

聲明轉(zhuǎn)換

聲明轉(zhuǎn)換對于聯(lián)合的安全性至關(guān)重要——它可能在聯(lián)合過程中的任意時刻發(fā)生。在 IP-STS 和 RP 屬于同一域的簡單聯(lián)合方案中,IP-STS 負責將聲明從身份驗證期間用戶所提供的一組初始身份標識聲明轉(zhuǎn)換為 RP 能夠用以授權(quán)調(diào)用的聲明。用戶可以為 IP-STS 提供任何支持的憑據(jù)類型來進行身份驗證,其中每個都會評估一組代表該憑據(jù)的聲明。

IP-STS 將這些聲明轉(zhuǎn)換成一組標準的應用程序聲明,RP 可以通過這組聲明授權(quán)調(diào)用——它們可以是角色或更精細的聲明,如創(chuàng)建、讀取、更新或刪除等權(quán)限。圖 12 中的圖表對這種方案進行了說明,其中 Admin 用戶登錄并被授予 Role 聲明和幾項 Action 聲明,其中包括創(chuàng)建、讀取、更新和刪除等。

圖 12 IP-STS 聲明轉(zhuǎn)換

這種類型的聲明轉(zhuǎn)換非常有用,因為對 STS 的身份驗證會得到一個令牌,其中包含授予該用戶的所有聲明。也有一些情況需要使用其他方法進行聲明轉(zhuǎn)換;例如為了減少頒發(fā)給那些僅與當前調(diào)用上下文相關(guān)的聲明、為了保護聲明的隱私性,或者為了促進跨域聯(lián)合等。

向經(jīng)過驗證的調(diào)用方授予與 RP 公開的所有功能相關(guān)的完整聲明列表既無必要,有時可能也并不合適。這不但會使列表變得非常長,而且還可能待授予的聲明取決于調(diào)用上下文,因此在不具備該上下文的情況下不應授予該聲明。例如,如果某用戶正在與客戶進行訂單交互,則只授予 Delete 聲明即可,但如果他正直接與客戶記錄交互,則不應授予該權(quán)限。

在其他一些類似情況中,如果 RP 能夠只從 IP-STS 請求少量聲明即可標識調(diào)用方,然后使用一組特定的僅適用于該調(diào)用上下文的附加聲明來請求一個新令牌,則將會非常有幫助。例如,如果用戶正在 RP 服務中調(diào)用 DeleteCustomer 操作,在授權(quán)執(zhí)行此操作之前,RP 將會調(diào)用從 IP-STS 傳入令牌的 RP-STS,并在 DeleteCustomer 操作的上下文中請求 Delete 聲明。如果該聲明存在,則調(diào)用將獲得授權(quán)。圖 13 中的圖表進一步說明了此示例。

此外,有時還存在 STS 頒發(fā)的聲明不應與 RP 直接共享的情況。例如,可以不必通過頒發(fā) Age 聲明來使 RP 了解用戶的年齡,RP 可以請求 IsOver13 聲明來確保調(diào)用方的年齡符合使用 RP 功能的條件。這樣可以確保 Age 聲明的實際值不會離開 STS。當然,這也表明 ST 將提供既能避免共享個人詳細信息又可以包含 RP 所需數(shù)據(jù)的聲明。

圖 13 RP-STS 聲明轉(zhuǎn)換

當屬于一個域的用戶被授予對另一個域中的 RP 的訪問權(quán)限時,聯(lián)合方案中也會發(fā)生聲明轉(zhuǎn)換。在這種情況下會涉及兩個 STS——用戶域的 IP-STS 和 RP 所屬域的 RP-STS。

同樣也是在這種情況下,IP-STS 會授予一些 RP-STS 能夠理解且達成一致的聲明;但這些聲明可能無法在 RP 應用程序中直接使用。相反,RP-STS 可能會負責將另一組可信聲明轉(zhuǎn)換為能夠被 RP 域所理解的聲明。

圖 14 說明了這種方案。當 Joe 試圖在沒有令牌的情況下訪問 RP 時,他將登錄到自己所在域(域 B)的 IP-STS。該請求將申請 RP 能夠理解的聲明(在本例中為 RPClaim),以便 IP-STS 知道應該頒發(fā) RP 能夠使用的令牌。當 RP-STS 接收到此令牌后,它將把該聲明轉(zhuǎn)換為 RP 專用的聲明。為了使此聯(lián)合方案能夠工作,必須在 RP-STS 和 IP-STS 之間建立信任關(guān)系,而且它們必須對 IP-STS 應該為其用戶頒發(fā)的將被授予對 RP 訪問權(quán)限的一組聲明達成一致。

圖 14 聯(lián)合方案中的聲明轉(zhuǎn)換

總結(jié)

對于那些熱衷于構(gòu)建自定義 STS 而又不需要 STS 平臺全部功能(如 Geneva 服務器)的用戶而言,Geneva 框架是一種非常受歡迎的實用工具。但即便使用 Geneva 框架,構(gòu)建自定義 STS 也不是一項簡單的任務,強烈建議您盡量使用完整功能的 STS 以減少出現(xiàn)安全漏洞的風險。

無論使用什么平臺,主動和被動 STS 實現(xiàn)的通信流程都是一致的,并且聲明轉(zhuǎn)換的原理也相同。與 STS 實現(xiàn)相關(guān)的其他概念還包括標識委派和逐級驗證。您可以在 Geneva 框架 SDK 中找到與這些及其他概念相關(guān)的示例和文檔。

Michele Leroux Bustamante 是 IDesign Inc. 的首席架構(gòu)師、圣地亞哥的 Microsoft 區(qū)域總監(jiān)和互聯(lián)系統(tǒng)的 Microsoft MVP。她的最新著作是《學習 WCF》。可通過 mlb@idesign.net 或訪問 idesign.net與她取得聯(lián)系。Michele 的博客網(wǎng)址是 dasblonde.net。

轉(zhuǎn)載于:https://www.cnblogs.com/frankzye/archive/2013/03/20/2971132.html

總結(jié)

以上是生活随笔為你收集整理的构建自定义安全令牌服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。