wcfwcf-bindingwcf-security

Cannot find a token authenticator for the 'System.IdentityModel.Tokens.UserNameSecurityToken' token type.


I am trying to get a third party Java client to communicate with a WCF service I have written.

I get the following exception when receiving the message:

Cannot find a token authenticator for the 'System.IdentityModel.Tokens.UserNameSecurityToken' token type. Tokens of that type cannot be accepted according to current security settings.

Here is my configuration:

Binding

<customBinding>
    <binding name="TestSecureBinding">
        <security authenticationMode="MutualCertificate" />
        <textMessageEncoding messageVersion="Soap11WSAddressing10" />
        <httpsTransport requireClientCertificate="true" maxReceivedMessageSize="5242880" />
    </binding>
</customBinding>

Behaviour:

  <serviceBehaviors>
    <behavior name="TestCertificateBehavior">
      <serviceCredentials>
        <clientCertificate>
          <certificate storeLocation="LocalMachine" x509FindType="FindBySubjectName" findValue="Test 01"/>
          <authentication certificateValidationMode="PeerTrust" trustedStoreLocation="LocalMachine" revocationMode="NoCheck"/>
        </clientCertificate>
        <serviceCertificate storeLocation="LocalMachine" x509FindType="FindBySubjectName" findValue="Test 01"/>
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>

Endpoint:

  <service name="TestService"
           behaviorConfiguration="TestCertificateBehavior">
    <endpoint
      name="TestEndpoint"
      address="https://localhost:443"
      contract="TestServiceContract"
      binding="customBinding"
      bindingConfiguration="TestSecureBinding">
    </endpoint>
    <host>
      <baseAddresses>
        <add baseAddress="https://localhost:443" />
      </baseAddresses>
    </host>

  </service>

Does anyone know what is causing this?


Solution

  • I have accepted that I can't do this in the config file and have resorted to creating the service host in code.

    Here is the full example of creating the binding, binding elements and creating the service host.

    Please note, you may not be using WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005W - you are probably using a more recent version than I am having to use - but just substitute that for the correct version for your service.

    var securityBindingElement = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
    securityBindingElement.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());
    securityBindingElement.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
    securityBindingElement.IncludeTimestamp = true;
    securityBindingElement.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.EncryptBeforeSign;
    
    var customBinding = new CustomBinding();
    customBinding.Elements.Add(securityBindingElement);
    customBinding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11WSAddressing10, Encoding.UTF8));
    customBinding.Elements.Add(new HttpsTransportBindingElement() { MaxReceivedMessageSize = 5242880 });
    
    ServiceHost customServiceHost = new ServiceHost(type);
    customServiceHost.AddServiceEndpoint(typeof(ITestServiceContract), customBinding, "https://localhost:443");
    customServiceHost.Open();