Search code examples
wcfwcf-securitywiffederated-identity

Why does this WCF call fail when passing in a federated security token


I'm trying to pass a security token from a client application into a WCF service for authentication.

For this example I'm just using the standard File, New WCF Application project and trying to call the GetData method.

I get the following exception on the client

{"The message could not be processed. This is most likely because the action 'http://tempuri.org/IService1/GetData' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint's binding."}

If I enable tracing on the WCF service I can see the following error

There was no channel that could accept the message with action 'http://tempuri.org/IService1/GetData'.

The Web.Config for my service looks like this

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />        
  </configSections>

  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>

  <!--Configure STS-->
  <system.identityModel>
    <identityConfiguration>
      <audienceUris>
        <add value="https://stsserver.security.int/myApp" />
      </audienceUris>
      <issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089">
        <trustedIssuers>
          <add thumbprint="‎3c8fc34bd483b07ba0d1509827fc4788c36247e4" name="StartSSL Login" />
        </trustedIssuers>
      </issuerNameRegistry>
      <certificateValidation certificateValidationMode="None"/>
    </identityConfiguration>
  </system.identityModel>

  <system.serviceModel>
    <bindings>
      <ws2007FederationHttpBinding>
        <binding name ="IdentityServer">
          <security mode="TransportWithMessageCredential">
          </security>
        </binding>
      </ws2007FederationHttpBinding>
    </bindings>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    <services>
      <service name="Services.Service1" behaviorConfiguration="CertificateBehavior">
        <endpoint name="ws" binding="ws2007FederationHttpBinding" bindingConfiguration="IdentityServer" contract="Services.IService1" address=""/>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="CertificateBehavior">
          <serviceCredentials>
            <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>    
</configuration>

The method in my client application that calls this WCF service looks like this

static void CallSecuredService(SecurityToken samlToken)
{
    var binding = new WS2007FederationHttpBinding((WSFederationHttpSecurityMode.TransportWithMessageCredential));
    binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey;
    binding.Security.Message.EstablishSecurityContext = false;

    var factory = new ChannelFactory<IService1>(binding, new EndpointAddress("https://localhost/myservice/Service1.svc"));
    factory.Credentials.SupportInteractive = false;
    factory.Credentials.UseIdentityConfiguration = true;
    var proxy = factory.CreateChannelWithIssuedToken(samlToken);

    Console.WriteLine(proxy.GetData(1));
}

Any pointers as to things I should check would be great as I'm at a bit of a loss with this one now. I'm not sure how I can debug this any further?


Solution

  • I finally managed to get past this error. The problem was a small miss match between the service and client bindings.

    Changing my bindings in the web.config to this fixed the issue

    <bindings>
      <ws2007FederationHttpBinding>
        <binding name ="IdentityServer">
          <security mode="TransportWithMessageCredential">
            <message issuedKeyType="BearerKey" establishSecurityContext="false"/>
          </security>
        </binding>
      </ws2007FederationHttpBinding>
    </bindings>