0
votes

On the same intranet-only box I have an IIS 8 hosted website that makes calls to a second IIS-hosted WCF service.

  • Windows authentication enabled for both applications (all others disabled)
  • Website is hosted under a domain service account.
  • WCF Services site hosted under the IIS AppPool user.

The binding looks like this:

<binding name="BasicHttpBinding_ServiceName" sendTimeout="00:05:00">
    <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows" />
    </security>
</binding>

When the website accesses the service using the netbios or ip address everything works fine. However, I would now like to use FQDNs for the production environment (http://services.company.local and http://web.company.local). As soon as I attempt to call the WCF service through the FQDN, I receive a 401 uauthorized with the following exception message:

MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate,NTLM'.

I've tried changing the clientCredentialType to NTLM and removing the negotiate provider from the IIS authentication (as suggested in another SO question) with no success (same error message, just the header received from the server was "NTLM" instead of "Negotiate,NTLM". From other research it seems that it might be an issue with the SPNs associated with the two subdomains created for this site, but I'm unsure 1. how to even check the SPNs for these domains, 2. What the SPNs should be, and 3. If this is even still relevant considering I am using kernel-mode authnetcation.

1

1 Answers

0
votes

The problem did turn out to be missing SPNs. To answer my own question, yes they are still relevant using kernel-mode authentication, the only difference being that they no longer need to be tied to the account under which the AppPool is running but instead only to the machine account.

For future reference, this SPN Checklist for Kerberos Authentication with IIS 7.0/7.5 is extremely helpful when initially configuring everything. In particular, accessing a site with a custom host name does require the creation of an additional SPN. For example, for a site hosted on the server named COMPANY-IIS-1 being accessed through http://services.company.local, the following command must be issued to create the appropriate SPN:

setspn -s http/services.company.local COMPANY-IIS-1

(-s is used instead of -a as suggested by the linked article since it first checks to make sure the spn does not already exist)


Debugging the issue was a little more challenging and required the use of WireShark installed on the web server box. I began a packet trace then attempted to access the webpage that caused the initial not authorized error to be received. I then filtered the packet capture for only kerberos traffic.

From there I was able to see the kerberos TGS-REQ and the resulting error, which turned out to be an S_PRINCIPAL_UNKNOWN error. By viewing the details of this response, I was able to see the SPN that was being used (outlined in red below), which is the SPN that needs to be created as described above in order for the authentication to succeed.

For the step-by-step procedure in troubleshooting the issue, this article proved extremely useful.

S_PRINCIPAL_UNKNOWN response in a WireShark packet capture


Finally, to see all SPNs associated with a given machine, the following command can be issued:

setspn -l [machine name]

e.g.

setspn -l COMPANY-IIS-1