2
votes

I'd like to authenticate a user using ADFS 2.0 to use a self-written WCF service. The service is ready and fully functional. Also the ADFS 2.0 is set up correctly.

When I set up the client binding in code and do the stuff there, everything works as expected. But when I like to use the configuration generated by "update service reference", the binding is wrong and doesn't work as expected.

Where am I missing something? Any hints welcome.

Error given

Unhandled Exception: System.ServiceModel.FaultException: The message with Action 'http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).

Server config:

<bindings>
  <ws2007FederationHttpBinding>
    <binding>
      <security mode="TransportWithMessageCredential">
        <message establishSecurityContext="false">
          <issuerMetadata address="https://sts.local.domain/adfs/services/trust/mex" />
          <issuer address="https://sts.local.domain/adfs/services/trust/2005/windowstransport" binding="ws2007HttpBinding" />
          <claimTypeRequirements>
            <add claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" isOptional="true" />
            <add claimType="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" isOptional="true" />
          </claimTypeRequirements>
        </message>
      </security>
    </binding>
  </ws2007FederationHttpBinding>
  <ws2007HttpBinding>
    <binding>
      <security mode="Transport">
        <transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
        <message clientCredentialType="None" establishSecurityContext="false" negotiateServiceCredential="true" />
      </security>
    </binding>
  </ws2007HttpBinding>
</bindings>

Client config (not working):

<bindings>
  <ws2007FederationHttpBinding>
    <binding name="WS2007FederationHttpBinding_IMyService" 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="TransportWithMessageCredential">
        <message algorithmSuite="Default" establishSecurityContext="false"
          issuedKeyType="SymmetricKey" negotiateServiceCredential="true">
          <issuer address="https://sts.local.domain/adfs/services/trust/2005/windowstransport" binding="ws2007HttpBinding" />
          <issuerMetadata address="https://sts.local.domain/adfs/services/trust/mex" />
          <tokenRequestParameters>
            <AppliesTo xmlns="http://schemas.xmlsoap.org/ws/2004/09/policy">
              <EndpointReference xmlns="http://www.w3.org/2005/08/addressing">
                <Address>https://service.machine.local/STSWcfService/MyService.svc</Address>
              </EndpointReference>
            </AppliesTo>
            <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>
  <ws2007HttpBinding>
    <binding>
      <security mode="Transport">
        <transport clientCredentialType="Windows" />
        <message clientCredentialType="Windows" establishSecurityContext="false" />
      </security>
    </binding>
  </ws2007HttpBinding>
</bindings>
<client>
  <endpoint address="https://service.machine.local/STSWcfService/MyService.svc"
    binding="ws2007FederationHttpBinding" bindingConfiguration="WS2007FederationHttpBinding_IMyService"
    contract="ServiceReference.IMyService" name="WS2007FederationHttpBinding_IMyService" />
</client>

Client binding in code (working):

private static SecurityToken GetToken()
{
    var factory = new WSTrustChannelFactory(new WindowsWSTrustBinding(SecurityMode.Transport), adfsEndPoint)
    {
        TrustVersion = TrustVersion.WSTrustFeb2005
    };

    var requestSecurityToken = new RequestSecurityToken
    {
        RequestType = WSTrustFeb2005Constants.RequestTypes.Issue,
        AppliesTo = new EndpointAddress(serviceEndPoint),
        KeyType = WSTrustFeb2005Constants.KeyTypes.Symmetric
    };

    var channel = factory.CreateChannel();
    return channel.Issue(requestSecurityToken);
}

private static void CallService(SecurityToken token)
{
    // create binding and turn off sessions
    var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
    binding.Security.Message.EstablishSecurityContext = false;

    // create factory and enable WIF plumbing
    var factory = new ChannelFactory<IMyService>(binding, new EndpointAddress(serviceEndPoint));
    factory.ConfigureChannelFactory();

    // turn off CardSpace - we already have the token
    factory.Credentials.SupportInteractive = false;

    var channel = factory.CreateChannelWithIssuedToken(token);
    foreach (var claim in channel.GetClaims())
    {
        Console.WriteLine("{0}\n {1}\n  {2} ({3})\n", claim.ClaimType, claim.Value, claim.Issuer, claim.OriginalIssuer);
    }
}
3
When update service reference fails, it generates some warnings; can you check the warnings from the Error window?daryal
I added the error message raised when using config files.Scoregraphic
There are no warnings during generation of the service reference. It just creates a basicHttpBinding, which I changed to a ws2007HttpBinding like it is used in the code version.Scoregraphic
Can you talk more about the client, is it WPF, ASP.NET, Silverlight?Eugene S.
Just an ordinary console application (atm), later on, it will be an WPF clientScoregraphic

3 Answers

1
votes

I think that your security mode and client credentials might not be matching.

Put this in your app.config (client and server) and make sure that the processes have write access to the directory.

 <system.diagnostics>
    <sources>
      <source name="Microsoft.IdentityModel" switchValue="Verbose">
        <listeners>
          <add name="xml" type="System.Diagnostics.XmlWriterTraceListener"
               initializeData="c:\temp\WIF.svclog" />
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
        <listeners>
          <add name="xml" type="System.Diagnostics.XmlWriterTraceListener"
               initializeData="c:\temp\WCF.svclog" />
        </listeners>
      </source>
    </sources>
    <trace autoflush="true" />
  </system.diagnostics>

This helped me a lot when trying to figure out what's wrong. I also suggest (only for testing) to include service exception in your faults.

<behaviors>  
    <serviceBehaviors> 
      <behavior>
       <serviceDebug includeExceptionDetailInFaults="true" />  
      </behavior>  
    </serviceBehaviors> 
</behaviors>   

Please do this and update your question with the errors from the log.

0
votes

You can create another binding section and give it another name than the one generated by Visual Studio. On a next update, the bindings will be merged.

-1
votes

I can't add comments for some reason - however I have seen WCF 'ignore' my wshttpbinding and take a basichttpbinding instead when I've altered my SVC file contents - it ends up relying on the scheme to determine the binding and as a result, ignores anything except basicHttpBinding for a http address.

Have a look there and see if that helps.