2010-08-26 17 views
3

我有:如何在服務端指定索賠類型要求,以便客戶端請求符合要求?

  • 也是身份提供者的被動STS「登錄應用程序」。
  • 有源STS WCF服務,可以受理ACTAS令牌
  • 一個網站依賴方
  • WCF服務的依賴方由網站調用。

所有這些使用Windows Identity Foundation和自定義STS代碼放在一起。活動目錄(ADFS)不涉及。

我現在有工作是:

  1. 用戶試圖訪問的網站的RP。
  2. 用戶被重定向到被動STS。
  3. 用戶登錄,獲取令牌,重定向回網站RP。
  4. 網站RP向WCF RP發起服務呼叫並傳遞ActAs令牌,以便委派發生。
  5. 主動STS看到ACTAS令牌進來,正確地設置了輸出特性,因此主要身份是ACTAS令牌和調用者的身份加入到演員鏈。
  6. WCF RP得到適當的令牌一切就緒,當前線程主要有正確的身份和權利要求所應當。

我想讓WCF RP向活動STS請求額外的聲明。

也就是說,在RST進入活動STS時,我希望它包含服務需要的聲明列表,以便可以提取這些額外的聲明(如果它們尚不存在)。

我已經找出瞭如何通過修改網站RP客戶端上的綁定來實現這一點,但我希望在WCF RP服務端指定需求。

我有它是與我使用綁定的感覺。我無法讓ws2007FederationHttpBinding與ActAs令牌一起工作,並且WIF Identity Training Kit中的所有示例都使用了customBinding,所以我也這樣做了,並且它終於奏效了。下面是從WCF RP顯示我的綁定配置的配置片斷:

<system.serviceModel> 
    <bindings> 
    <customBinding> 
     <binding name="CustomBinding_FederatedService"> 
     <security 
      authenticationMode="IssuedTokenForCertificate" 
      messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10"> 
      <issuedTokenParameters tokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"> 
      <issuer address="http://localhost:38901/ActiveSts.svc/IWSTrust13" /> 
      <issuerMetadata address="http://localhost:38901/ActiveSts.svc/mex" /> 
      </issuedTokenParameters> 
     </security> 
     <textMessageEncoding> 
      <readerQuotas maxArrayLength="32767" /> 
     </textMessageEncoding> 
     <httpTransport /> 
     </binding> 
    </customBinding> 
    </bindings> 
</system.serviceModel> 

如果我改變對調用Web站點以指示issuedTokenParameters部分claimTypeRequirements的配置,主動STS實際上沒有看到要求索賠清單在RST ...但這是在調用的網站,這對我來說是有問題的。

如何使WCF RP能夠指定其所需的附加聲明,而無需在呼叫網站上覆制該配置?

如果是,的確,有約束力的問題,它會幫助,如果你能告訴我什麼給我上面得到了相當的配置。我可以通過適當的修改更新網站和WCF服務,但是我需要服務(或服務上的行爲或服務配置)來控制它所需的聲明列表。該服務不應接受缺少所需索賠的請求。

回答

4

事實證明,你必須要做到這一點的方式...

  1. 想出一個辦法來獲取客戶端上的索賠要求。這可能是某種中央配置服務,WS-Policy/Metadata Exchange或任何你喜歡的。
  2. 手動爲STS創建令牌請求。使用WSTrustChannelFactory手動請求ActAs令牌(或新令牌),而不是使用Microsoft.IdentityModel CreateChannelActingAs(token)擴展方法。
  3. 將手動請求的令牌添加到傳出通道參數。

請注意,這不會完全消除您的客戶端了解索賠要求列表的需求,但它確實使您能夠以某種方式集中配置該配置,甚至可以使用服務本身來提供該列表的索賠要求。不幸的是,在Microsoft.IdentityModel棧中沒有任何東西可以爲你做這一切。客戶端絕對需要知道索賠要求列表,因爲安全令牌的請求是作爲客戶端通信的一部分發出的,而不是由於服務操作請求進入服務而發佈的。

無論如何,您可以看到一些體面的解釋WSTrustChannelFactoryWSTrustChannelon the MSDN web site。我的解決方案基於此。

歸結沒有所有的錯誤處理,等等,代碼基本上是這樣的:

// You need the channel factory so you can get info about the endpoint. 
var factory = new ChannelFactory<IService>(); 

// Get the issuedTokenParameters information from the binding. 
// You see this in the XML config but it's painful to access. 
var tokenParameters = factory.Endpoint.Binding 
    .CreateBindingElements() 
    .OfType<SecurityBindingElement>().First() 
    .EndpointSupportingTokenParameters 
    .Endorsing.OfType<IssuedSecurityTokenParameters>().First(); 

// Prepare the RST. 
var trustChannelFactory = new WSTrustChannelFactory(tokenParameters.IssuerBinding, tokenParameters.IssuerAddress); 
var trustChannel = (WSTrustChannel)trustChannelFactory.CreateChannel(); 
var rst = new RequestSecurityToken(RequestTypes.Issue); 
rst.AppliesTo = factory.Endpoint.Address; 

// If you're doing delegation, set the ActAs value. 
var principal = Thread.CurrentPrincipal as IClaimsPrincipal; 
var bootstrapToken = principal.Identities[0].BootstrapToken; 
rst.ActAs = new SecurityTokenElement(bootstrapToken); 

// Here's where you can look up claims requirements dynamically. 
rst.Claims.Add(new RequestClaim("http://dynamically-added-claim")); 

// Get the token and attach it to the channel before making a request. 
RequestSecurityTokenResponse rstr = null; 
var issuedToken = trustChannel.Issue(rst, out rstr); 
var fccParameters = new FederatedClientCredentialsParameters(); 
fccParameters.IssuedSecurityToken = issuedToken; 
var channel = factory.CreateChannel(); 
((IChannel)channel).GetProperty<ChannelParameterCollection>().Add(fccParameters); 

// NOW you can make the request. 
channel.DoWork(); 

這也可以讓你發出的令牌,如果你願意的話,以優化一些周圍流動通訊的高速緩存系統。如果您不想動態地插入聲明要求,或者如果您使用XML配置並將其複製到服務器和客戶端上,則不必這樣做。 CreateChannelActingAs(token)擴展方法和整個Microsoft.IdentityModel堆棧爲您處理此問題。