title: Securing backend WCF service with WIF using ADFS2 as IP
body: <p>I’m having an issue using ADFS2 to secure a back-end WCF service that is being called from Passively Federated Website. I have the passive federation working on the website, but the back-end service is giving me problems. </p>
  
  <p><strong>The pieces of the puzzle.</strong> </p>
  
  <ol>
  <li>Silverlight Client that is being served from Passively Federated Website. </li>
  <li>The Silverlight calls a WCF service (App Service), hosted on the passively Federated Website.</li>
  <li>I have SaveBootstrapToken set to true in the config.</li>
  <li>From the App Service, I want to call a back-end WCF service using BootstrapToken with the ActAs scenarion.</li>
  <li>Federated Website and Back-end WCF service are setup as separate RPs in the ADFS2, token encryption is turned on. Both are allowed to delegate.</li>
  </ol>
  
  <p><strong>Back-end Service configuration:</strong></p>
  
  <p>I have WIF incorporated into the pipeline using  behavior extension.</p>
  
  <pre><code>&lt;ws2007FederationHttpBinding&gt;
    &lt;binding name="WS2007FederationHttpBinding_IQuoteService"&gt;
      &lt;security mode="TransportWithMessageCredential"&gt;
        &lt;message establishSecurityContext="false"&gt;
          &lt;issuer address="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256"&gt;
          &lt;/issuer&gt;
          &lt;issuerMetadata address="https://myADFSserver/adfs/services/trust/mex"&gt;
          &lt;/issuerMetadata&gt;
        &lt;/message&gt;
      &lt;/security&gt;
    &lt;/binding&gt;
  &lt;/ws2007FederationHttpBinding&gt;
  
  
  &lt;behaviors&gt;
    &lt;serviceBehaviors&gt;
      &lt;behavior name=""&gt;
        &lt;federatedServiceHostConfiguration name="Service.QuoteService" /&gt;
        &lt;serviceMetadata httpGetEnabled="true" /&gt;
        &lt;serviceDebug includeExceptionDetailInFaults="false" /&gt;
        &lt;serviceCredentials&gt;
          &lt;serviceCertificate findValue="000000000000000000000000000000" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" /&gt;
        &lt;/serviceCredentials&gt;
      &lt;/behavior&gt;
    &lt;/serviceBehaviors&gt;
  &lt;/behaviors&gt;
  
  &lt;services&gt;
    &lt;service name="Service.QuoteService"&gt;
      &lt;endpoint address="" binding="ws2007FederationHttpBinding" contract="Service.IQuoteService" bindingConfiguration="WS2007FederationHttpBinding_IQuoteService" /&gt;
      &lt;endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /&gt;
    &lt;/service&gt;
  &lt;/services&gt;
  </code></pre>
  
  <p><strong>Client Configuration</strong></p>
  
  <p>When add the service using Add Service Reference tooling, the following config on the client gets created:</p>
  
  <pre><code>&lt;customBinding&gt;
    &lt;binding name="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256"&gt;
      &lt;security defaultAlgorithmSuite="Default" authenticationMode="IssuedTokenOverTransport"
        requireDerivedKeys="false" securityHeaderLayout="Strict" includeTimestamp="true"
        keyEntropyMode="CombinedEntropy" messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10"&gt;
        &lt;issuedTokenParameters keySize="256" keyType="SymmetricKey" tokenType=""&gt;
          &lt;additionalRequestParameters&gt;
            &lt;trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"&gt;
              &lt;trust:KeyType&gt;http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey&lt;/trust:KeyType&gt;
              &lt;trust:KeySize&gt;256&lt;/trust:KeySize&gt;
              &lt;trust:KeyWrapAlgorithm&gt;http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p&lt;/trust:KeyWrapAlgorithm&gt;
              &lt;trust:EncryptWith&gt;http://www.w3.org/2001/04/xmlenc#aes256-cbc&lt;/trust:EncryptWith&gt;
              &lt;trust:SignatureAlgorithm&gt;http://www.w3.org/2000/09/xmldsig#hmac-sha1&lt;/trust:SignatureAlgorithm&gt;
              &lt;trust:CanonicalizationAlgorithm&gt;http://www.w3.org/2001/10/xml-exc-c14n#&lt;/trust:CanonicalizationAlgorithm&gt;
              &lt;trust:EncryptionAlgorithm&gt;http://www.w3.org/2001/04/xmlenc#aes256-cbc&lt;/trust:EncryptionAlgorithm&gt;
            &lt;/trust:SecondaryParameters&gt;
          &lt;/additionalRequestParameters&gt;
        &lt;/issuedTokenParameters&gt;
        &lt;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" /&gt;
        &lt;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" /&gt;
        &lt;secureConversationBootstrap /&gt;
      &lt;/security&gt;
      &lt;textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
        messageVersion="Default" writeEncoding="utf-8"&gt;
        &lt;readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
          maxBytesPerRead="4096" maxNameTableCharCount="16384" /&gt;
      &lt;/textMessageEncoding&gt;
      &lt;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" /&gt;
    &lt;/binding&gt;
  &lt;/customBinding&gt;
  
  
  &lt;ws2007FederationHttpBinding&gt;
    &lt;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"&gt;
      &lt;readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" /&gt;
      &lt;reliableSession ordered="true" inactivityTimeout="00:10:00"
        enabled="false" /&gt;
      &lt;security mode="Message"&gt;
        &lt;message algorithmSuite="Default" issuedKeyType="SymmetricKey"
          negotiateServiceCredential="true"&gt;
          &lt;issuer address="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256"
            binding="customBinding" bindingConfiguration="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256" /&gt;
          &lt;issuerMetadata address="https://myADFSserver/adfs/services/trust/mex" /&gt;
          &lt;tokenRequestParameters&gt;
            &lt;trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"&gt;
              &lt;trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"&gt;http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey&lt;/trust:KeyType&gt;
              &lt;trust:KeySize xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"&gt;256&lt;/trust:KeySize&gt;
              &lt;trust:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity"
                xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"&gt;
                &lt;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" /&gt;
                &lt;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" /&gt;
              &lt;/trust:Claims&gt;
              &lt;trust:KeyWrapAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"&gt;http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p&lt;/trust:KeyWrapAlgorithm&gt;
              &lt;trust:EncryptWith xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"&gt;http://www.w3.org/2001/04/xmlenc#aes256-cbc&lt;/trust:EncryptWith&gt;
              &lt;trust:SignWith xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"&gt;http://www.w3.org/2000/09/xmldsig#hmac-sha1&lt;/trust:SignWith&gt;
              &lt;trust:CanonicalizationAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"&gt;http://www.w3.org/2001/10/xml-exc-c14n#&lt;/trust:CanonicalizationAlgorithm&gt;
              &lt;trust:EncryptionAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"&gt;http://www.w3.org/2001/04/xmlenc#aes256-cbc&lt;/trust:EncryptionAlgorithm&gt;
            &lt;/trust:SecondaryParameters&gt;
          &lt;/tokenRequestParameters&gt;
        &lt;/message&gt;
      &lt;/security&gt;
    &lt;/binding&gt;
  &lt;/ws2007FederationHttpBinding&gt;
  
  
  &lt;client&gt;
    &lt;endpoint address="http://myServiceHost/Service/QuoteService.svc"
      binding="ws2007FederationHttpBinding" bindingConfiguration="WS2007FederationHttpBinding_IQuoteService"
      contract="QuoteService.IQuoteService" name="WS2007FederationHttpBinding_IQuoteService"&gt;
      &lt;identity&gt;
        &lt;certificate encodedValue="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" /&gt;
      &lt;/identity&gt;
    &lt;/endpoint&gt;
  &lt;/client&gt;
  </code></pre>
  
  <p><strong>Here's the Service Client Code:</strong></p>
  
  <pre><code>List&lt;Quote&gt; quoteList = new List&lt;Quote&gt;();
  
  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&lt;IQuoteServiceChannel&gt; factory = new ChannelFactory&lt;IQuoteServiceChannel&gt;("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;
  </code></pre>
  
  <p><strong>This is the exception I get:</strong></p>
  
  <pre><code>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&amp; supportingTokens)
         at System.ServiceModel.Security.SymmetricSecurityProtocol.TryGetTokenSynchronouslyForOutgoingSecurity(Message message, SecurityProtocolCorrelationState correlationState, Boolean isBlockingCall, TimeSpan timeout, SecurityToken&amp; token, SecurityTokenParameters&amp; tokenParameters, SecurityToken&amp; prerequisiteWrappingToken, IList`1&amp; supportingTokens, SecurityProtocolCorrelationState&amp; newCorrelationState)
         at System.ServiceModel.Security.SymmetricSecurityProtocol.SecureOutgoingMessageCore(Message&amp; message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
         at System.ServiceModel.Security.MessageSecurityProtocol.SecureOutgoingMessage(Message&amp; 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&amp; 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[]&amp; outputs)
         at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; 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&amp; msgData, Int32 type)
              at System.ServiceModel.ICommunicationObject.Open(TimeSpan timeout)
              at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
         InnerException:
  </code></pre>
  
  <p>I'm sure I'm missing something in the configuration and/or code can someone help me out?</p>