2

Some clients need to be able to connect to our WCF SOAP services using Basic authentication, while others need to use Windows authentication. We normally host our services in IIS, although we do provide a less-developed Windows Service hosting option.

It's my understanding that it is not possible to configure one endpoint to support both Basic and Windows authentication. So we have two endpoints per service.

<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicBinding" contract="SomeContract" bindingNamespace="http://www.somewhere.com/Something" />
<endpoint address="win" binding="basicHttpBinding" bindingConfiguration="WindowsBinding" contract="SomeContract" bindingNamespace="http://www.somewhere.com/Something" />

...

<bindings>
  <basicHttpBinding>
    <binding name="BasicBinding">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Basic"/>
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
    <binding name="WindowsBinding">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows"/>
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

These are in the same Web Application in IIS. That Web Application has both Basic and Windows authentication enabled (else one of the above bindings wouldn't work).

When a client uses the Windows-authenticated endpoint (with "win" on the end of URL), this typically works fine. When the initial request doesn't contain any authentication information, a negotiation takes place between the client and IIS, they settle on Windows authentication and all goes well.

When a client uses the Basic-authenticated endpoint (without "win" on the end of URL), this works if they include the Authorization HTTP header with the correct encoded credentials in it. However, if they do not include any authentication information in the initial request, the negotiation ends up choosing Windows authentication. This gets the request past IIS security, but WCF then refuses the request, because it's going to a Basic-authenticated endpoint.

I am rather hazy on exactly what's happening in the negotiation. But it seems to me that IIS offers all authentication methods enabled for the Web Application (i.e. Basic and Windows), even though the particular WCF endpoint URL for the request only supports Basic.

I would like to know if there is anything we can do in IIS to make the negotiation come up with the right answer: that is, if the request is to a Basic-authenticated endpoint, tell the client to use Basic. Of course, we still want the negotiation to end up choosing Windows, when the request went to the Windows-authenticated endpoint.

If there isn't, then do you think we would be better off concentrating on our Windows Service-hosted version of the services? Or would that have similar problems somehow?

Final note: we do use Basic with HTTP for some internal uses, but we do know that this is an insecure combination. So we typically turn on HTTPS for production use; I've left that out here, for simplicity.

PeteAC
  • 789
  • 8
  • 19
  • I since found out about clientCredentialType="InheritedFromHost" This is new in .Net 4.5 and seems to help with my issue. I am not yet sure whether it solves all the problems. – PeteAC Feb 18 '14 at 16:27

1 Answers1

0

Yes, clientCredentialType="InheritedFromHost" solves the problem for me. This, new in .Net 4.5, means that one can now use the same endpoint URL for more than one authentication type. IIS settings control what authentication is allowed, meaning no longer possible to get IIS and WCF settings in conflict.

PeteAC
  • 789
  • 8
  • 19