使用 ADFS2 作为 IP 使用 WIF 保护后端 WCF 服务

Posted

技术标签:

【中文标题】使用 ADFS2 作为 IP 使用 WIF 保护后端 WCF 服务【英文标题】:Securing backend WCF service with WIF using ADFS2 as IP 【发布时间】:2011-09-29 17:14:53 【问题描述】:

我在使用 ADFS2 保护从被动联合网站调用的后端 WCF 服务时遇到问题。我有在网站上工作的被动联合,但后端服务给我带来了问题。

拼图。

    从被动联合网站提供服务的 Silverlight 客户端。 Silverlight 调用托管在被动联合网站上的 WCF 服务(应用服务)。 我在配置中将 SaveBootstrapToken 设置为 true。 从应用服务,我想使用带有 ActAs 场景的 BootstrapToken 调用后端 WCF 服务。 联合网站和后端 WCF 服务在 ADFS2 中设置为单独的 RP,令牌加密已打开。两者都可以委托。

后端服务配置:

我已使用行为扩展将 WIF 合并到管道中。

<ws2007FederationHttpBinding>
  <binding name="WS2007FederationHttpBinding_IQuoteService">
    <security mode="TransportWithMessageCredential">
      <message establishSecurityContext="false">
        <issuer address="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256">
        </issuer>
        <issuerMetadata address="https://myADFSserver/adfs/services/trust/mex">
        </issuerMetadata>
      </message>
    </security>
  </binding>
</ws2007FederationHttpBinding>


<behaviors>
  <serviceBehaviors>
    <behavior name="">
      <federatedServiceHostConfiguration name="Service.QuoteService" />
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
      <serviceCredentials>
        <serviceCertificate findValue="000000000000000000000000000000" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>

<services>
  <service name="Service.QuoteService">
    <endpoint address="" binding="ws2007FederationHttpBinding" contract="Service.IQuoteService" bindingConfiguration="WS2007FederationHttpBinding_IQuoteService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>

客户端配置

使用添加服务引用工具添加服务时,会在客户端创建以下配置:

<customBinding>
  <binding name="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256">
    <security defaultAlgorithmSuite="Default" authenticationMode="IssuedTokenOverTransport"
      requireDerivedKeys="false" securityHeaderLayout="Strict" includeTimestamp="true"
      keyEntropyMode="CombinedEntropy" messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10">
      <issuedTokenParameters keySize="256" keyType="SymmetricKey" tokenType="">
        <additionalRequestParameters>
          <trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
            <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</trust:KeyType>
            <trust:KeySize>256</trust:KeySize>
            <trust:KeyWrapAlgorithm>http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p</trust:KeyWrapAlgorithm>
            <trust:EncryptWith>http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptWith>
            <trust:SignatureAlgorithm>http://www.w3.org/2000/09/xmldsig#hmac-sha1</trust:SignatureAlgorithm>
            <trust:CanonicalizationAlgorithm>http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm>
            <trust:EncryptionAlgorithm>http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm>
          </trust:SecondaryParameters>
        </additionalRequestParameters>
      </issuedTokenParameters>
      <localClientSettings cacheCookies="true" detectReplays="false"
        replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
        replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
        sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true"
        timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
      <localServiceSettings detectReplays="false" issuedCookieLifetime="10:00:00"
        maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
        negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
        sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
        reconnectTransportOnFailure="true" maxPendingSessions="128"
        maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
      <secureConversationBootstrap />
    </security>
    <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
      messageVersion="Default" writeEncoding="utf-8">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
    </textMessageEncoding>
    <httpsTransport manualAddressing="false" maxBufferPoolSize="524288"
      maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
      bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
      keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
      realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
      useDefaultWebProxy="true" requireClientCertificate="false" />
  </binding>
</customBinding>


<ws2007FederationHttpBinding>
  <binding name="WS2007FederationHttpBinding_IQuoteService" closeTimeout="00:01:00"
    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
    maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
    textEncoding="utf-8" useDefaultWebProxy="true">
    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
      maxBytesPerRead="4096" maxNameTableCharCount="16384" />
    <reliableSession ordered="true" inactivityTimeout="00:10:00"
      enabled="false" />
    <security mode="Message">
      <message algorithmSuite="Default" issuedKeyType="SymmetricKey"
        negotiateServiceCredential="true">
        <issuer address="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256"
          binding="customBinding" bindingConfiguration="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256" />
        <issuerMetadata address="https://myADFSserver/adfs/services/trust/mex" />
        <tokenRequestParameters>
          <trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
            <trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</trust:KeyType>
            <trust:KeySize xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">256</trust:KeySize>
            <trust:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity"
              xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
              <wsid:ClaimType Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
                Optional="true" xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity" />
              <wsid:ClaimType Uri="http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
                Optional="true" xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity" />
            </trust:Claims>
            <trust:KeyWrapAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p</trust:KeyWrapAlgorithm>
            <trust:EncryptWith xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptWith>
            <trust:SignWith xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2000/09/xmldsig#hmac-sha1</trust:SignWith>
            <trust:CanonicalizationAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm>
            <trust:EncryptionAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm>
          </trust:SecondaryParameters>
        </tokenRequestParameters>
      </message>
    </security>
  </binding>
</ws2007FederationHttpBinding>


<client>
  <endpoint address="http://myServiceHost/Service/QuoteService.svc"
    binding="ws2007FederationHttpBinding" bindingConfiguration="WS2007FederationHttpBinding_IQuoteService"
    contract="QuoteService.IQuoteService" name="WS2007FederationHttpBinding_IQuoteService">
    <identity>
      <certificate encodedValue="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
    </identity>
  </endpoint>
</client>

这是服务客户端代码:

List<Quote> quoteList = new List<Quote>();

ClaimsPrincipal myClaimsPrincipal = System.Web.HttpContext.Current.User as ClaimsPrincipal;
SecurityToken bootstrapToken = myClaimsPrincipal.Identities[0].BootstrapToken;
if (bootstrapToken == null)

    throw new Exception("bootstrap tokein is null. Logout and try again.");


ChannelFactory<IQuoteServiceChannel> factory = new ChannelFactory<IQuoteServiceChannel>("WS2007FederationHttpBinding_IQuoteService");
factory.Credentials.SupportInteractive = false;

factory.Credentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "0000000000000000000000000000");
factory.ConfigureChannelFactory();

IQuoteServiceChannel channel;

//Create the channel with the bootstrap token
channel = factory.CreateChannelActingAs(bootstrapToken);

try

    quoteList = channel.GetQuotes(quoteUser);
    channel.Close();

catch (SecurityAccessDeniedException sadex)

    channel.Abort();
    throw;

catch (CommunicationException exception)

    channel.Abort();
    throw;

catch (TimeoutException timeoutEx)

    channel.Abort();
    throw;

catch (Exception ex)

    channel.Abort();
    throw;


return quoteList;

这是我得到的例外:

System.ServiceModel.Security.SecurityNegotiationException was unhandled by user code
  Message=SOAP security negotiation with 'https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256' for target 'https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256' failed. See inner exception for more details.
  Source=mscorlib
  StackTrace:
    Server stack trace: 
       at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
       at System.ServiceModel.Security.IssuanceTokenProviderBase`1.GetTokenCore(TimeSpan timeout)
       at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
       at Microsoft.IdentityModel.Protocols.WSTrust.FederatedSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
       at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
       at System.ServiceModel.Security.SecurityProtocol.TryGetSupportingTokens(SecurityProtocolFactory factory, EndpointAddress target, Uri via, Message message, TimeSpan timeout, Boolean isBlockingCall, IList`1& supportingTokens)
       at System.ServiceModel.Security.SymmetricSecurityProtocol.TryGetTokenSynchronouslyForOutgoingSecurity(Message message, SecurityProtocolCorrelationState correlationState, Boolean isBlockingCall, TimeSpan timeout, SecurityToken& token, SecurityTokenParameters& tokenParameters, SecurityToken& prerequisiteWrappingToken, IList`1& supportingTokens, SecurityProtocolCorrelationState& newCorrelationState)
       at System.ServiceModel.Security.SymmetricSecurityProtocol.SecureOutgoingMessageCore(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
       at System.ServiceModel.Security.MessageSecurityProtocol.SecureOutgoingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
       at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
       at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout)
       at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
       at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
       at System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
       at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
       at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
    Exception rethrown at [0]: 
       at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
       at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
       at OMG.Admin.DemoApp.Business.QuoteService.IQuoteService.GetQuotes(User quoteUser)
       at OMG.Admin.DemoApp.Business.QuoteServiceClient.GetQuotes(User quoteUser) in C:\OMG_TFS01\OMG.Admin\OMG.Admin.DemoApp\OMG.Admin.DemoApp.Business\QuoteServiceClient.cs:line 131
       at OMG.Admin.DemoApp.Business.QuoteBO.GetQuoteList() in C:\OMG_TFS01\OMG.Admin\OMG.Admin.DemoApp\OMG.Admin.DemoApp.Business\QuoteBO.cs:line 26
       at OMG.Admin.DemoApp.Web.Services.DemoAppService.GetQuotes() in C:\OMG_TFS01\OMG.Admin\OMG.Admin.DemoApp\OMG.Admin.DemoApp.Web\Services\DemoAppService.svc.cs:line 27
       at SyncInvokeGetQuotes(Object , Object[] , Object[] )
       at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
       at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
  InnerException: System.InvalidOperationException
       Message=The address of the security token issuer is not specified. An explicit issuer address must be specified in the binding for target 'https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256' or the local issuer address must be configured in the credentials.
       Source=mscorlib
       StackTrace:
         Server stack trace: 
            at System.ServiceModel.ClientCredentialsSecurityTokenManager.CreateIssuedSecurityTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
            at System.ServiceModel.ClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement, Boolean disableInfoCard)
            at Microsoft.IdentityModel.Protocols.WSTrust.FederatedClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
            at System.ServiceModel.Security.SecurityProtocol.AddSupportingTokenProviders(SupportingTokenParameters supportingTokenParameters, Boolean isOptional, IList`1 providerSpecList)
            at System.ServiceModel.Security.SecurityProtocol.OnOpen(TimeSpan timeout)
            at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
            at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
            at System.ServiceModel.Channels.SecurityChannelFactory`1.ClientSecurityChannel`1.OnOpen(TimeSpan timeout)
            at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
            at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
            at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
         Exception rethrown at [0]: 
            at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
            at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
            at System.ServiceModel.ICommunicationObject.Open(TimeSpan timeout)
            at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
       InnerException:

我确定我在配置和/或代码中遗漏了一些东西,有人可以帮我吗?

【问题讨论】:

我在客户端上尝试了不同的配置更改,并认为我的问题与 ws2007Federation 调用 ADFS 的方式有关。这几乎就像我在联合时需要一个无安全绑定来与 ADFS 对话 我能够将 bootstrapToken 转换为 SamlXMl 并在令牌 &lt;saml:ConfirmationMethod&gt;urn:oasis:names:tc:SAML:1.0:cm:bearer&lt;/saml:ConfirmationMethod&gt; 中看到这一点,这是否意味着我不能使用 bootstrap 令牌进行身份验证?因为它不是对称密钥而是承载密钥? ADFS 配置起来简直就是一场噩梦,并且在 Web 上提供的示例很少。由于这个原因,它的吸收率并不高。我建议您避免使用它并使用更传统的方法来实现您的安全性。我们试图在我们的项目中使用它,但不得不在一个月后放弃它。 好点子,你应该对这个问题投赞成票,这样它就会有更多的知名度。我真的很想看到其他一些答案——我正在努力地看这个问题! :) 这是我正在做的一个项目的要求,所以我不能放弃它。 【参考方案1】:

我得到了这个方案,这是任何有兴趣的人的解决方案。

关注Dominick Baier的帖子以获得想法/代码:http://leastprivilege.com/2010/10/14/wif-adfs-2-and-wcfpart-5-service-client-more-flexibility-with-wstrustchannelfactory/

我将后端 WCF 服务配置更改为:

<microsoft.identityModel>
  <service>
    <audienceUris>
      <add value="https://localhost/Service/QuoteService.svc" />
      <add value="https://localhost/Service/" />
    </audienceUris>
    <serviceCertificate>
      <certificateReference x509FindType="FindByThumbprint" findValue="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
    </serviceCertificate>
    <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
      <trustedIssuers>
        <add thumbprint="000000000000000000000000000000000000" name="http://myADFSserver/adfs/services/trust" />
      </trustedIssuers>
    </issuerNameRegistry>
    <certificateValidation certificateValidationMode="None" />
  </service>
</microsoft.identityModel>

<system.serviceModel>
  <services>
    <service name="Service.QuoteService">
      <endpoint address=""
                binding="ws2007FederationHttpBinding"
                contract="Service.IQuoteService" />
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    </service>
  </services>
  <bindings>
    <ws2007FederationHttpBinding>
      <binding>
        <security mode="TransportWithMessageCredential">
          <message establishSecurityContext="false">
            <issuerMetadata address="https://myADFSserver/adfs/services/trust/mex" />
          </message>
        </security>
      </binding>
    </ws2007FederationHttpBinding>
  </bindings>

  <behaviors>
    <serviceBehaviors>
      <behavior>
        <serviceMetadata httpsGetEnabled="true" />
        <federatedServiceHostConfiguration />
      </behavior>
    </serviceBehaviors>
  </behaviors>

  <extensions>
    <behaviorExtensions>
      <add name="federatedServiceHostConfiguration"
           type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtensionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    </behaviorExtensions>
  </extensions>
</system.serviceModel>

我不再在客户端使用 WCF 配置,这一切都在代码中完成。

这是客户端代码:

public QuoteServiceClient()

    SecurityToken actAsToken = this.GetDelegatedTokenUsername();
    var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
    binding.Security.Message.EstablishSecurityContext = false;

    ChannelFactory<IQuoteServiceChannel> factory = 
                    new ChannelFactory<IQuoteServiceChannel>(binding, new EndpointAddress(svcEndpoint));
    factory.ConfigureChannelFactory<IQuoteServiceChannel>();
    factory.Credentials.SupportInteractive = false;

    this.channel = factory.CreateChannelWithIssuedToken<IQuoteServiceChannel>(actAsToken);


private SecurityToken GetDelegatedTokenUsername()

    var binding = new UserNameWSTrustBinding();
    binding.SecurityMode = SecurityMode.TransportWithMessageCredential;

    //UserNameMixed is this endpoint "/adfs/services/trust/13/usernamemixed"
    WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory(binding, new EndpointAddress(UserNameMixed));
    trustChannelFactory.TrustVersion = System.ServiceModel.Security.TrustVersion.WSTrust13;

    trustChannelFactory.Credentials.SupportInteractive = false;
    //Some User Account
    //It's used to access the ADFS Server
    //Act as is the actual Identity that Will be used.
    //If you use one of windows bindings (ex. windowstransport), you wont need this.
    //The AppPool identity will be used then.
    trustChannelFactory.Credentials.UserName.UserName = @"domain\username";
    trustChannelFactory.Credentials.UserName.Password = "password";

    try
    
        RequestSecurityToken rst = new RequestSecurityToken();
        rst.RequestType = WSTrust13Constants.RequestTypes.Issue;
        rst.AppliesTo = new EndpointAddress(ServiceAppliesTo);

        //This part will give you identity of logged in user
        rst.ActAs = new SecurityTokenElement(this.GetBootStrapToken());

        var channel = trustChannelFactory.CreateChannel();
        RequestSecurityTokenResponse rstr = null;
        SecurityToken delegatedToken = channel.Issue(rst, out rstr);

        return delegatedToken;
    
    catch (Exception ex)
    
        throw new Exception(ex.Message, ex);
    
    finally
    
        try
        
            if (trustChannelFactory.State == CommunicationState.Faulted)
            
                trustChannelFactory.Abort();
            
            else
            
                trustChannelFactory.Close();
            
        
        catch (Exception)
         
    


private SecurityToken GetBootStrapToken()

    ClaimsPrincipal myClaimsPrincipal = System.Web.HttpContext.Current.User as ClaimsPrincipal;
    SecurityToken bootstrapToken = myClaimsPrincipal.Identities[0].BootstrapToken;

    if (bootstrapToken == null)
    
        throw new Exception("bootstrap tokein is null. Logout and try again.");
    
    return bootstrapToken;

这一切都很好,但您不会对后端 WCF 服务拥有适当的声明。使用这篇很棒的文章,我能够整理出 ADFS 中的声明内容:http://technet.microsoft.com/en-us/library/adfs2-identity-delegation-step-by-step-guide.aspx。 向下滚动到在 CONTOSODC 上启用身份委派和修复声明发布规则。我还从被动联合网站中删除了声明加密。

执行此操作后,我在应用服务和后端 WCF 服务中拥有相同的声明。

我希望这可以帮助和我在同一条船上的人。

【讨论】:

感谢您的跟进!我们正在开始实施,这非常有帮助。 我再次在这个线程中徘徊,寻找其他东西。我冒昧地编辑了您的帖子以更新指向 LeastPrivilege.com 的链接

以上是关于使用 ADFS2 作为 IP 使用 WIF 保护后端 WCF 服务的主要内容,如果未能解决你的问题,请参考以下文章

ADFS 2.0 中的 SAML 2 签名错误

WIF(使用 Thinktecture Identity Server)和双工 WCF 通道

android真机能使用wif,且可以上网i,但却无法连接电脑搭建的服务器??为啥?

在没有域名的情况下登录 Azure Active Directory

通过将 IP 列入白名单和更改别名来保护 phpMyAdmin

使用WIF,audienceUris和realm有啥区别?