I was trying to set up a Java service using the SPNEGO servlet filter and a listen port of 8080 for authentication on a host that is also running web applications hosted in IIS7.

I followed the SPNEGO installation instructions and created an SPN for HTTP/canonical.host.name, bound to the user performing the authentication for the Java service.

After this change, the Java service is able to authenticate clients via SPNEGO, but IIS7 application pools running with custom identities (i.e. user names instead of ApplicationPoolIdentity) are suddenly unable to authenticate.

What I don't understand here:

How does Kerberos authentication work for IIS when there is no SPN for HTTP/canonical.host.name defined using (as checked via setspn -Q)? Clients still request and receive tickets for exactly this SPN.

Out of interest, we tried running the application pools with the identity of the Java service that successfully authenticates. It still did not work as long as the SPN was defined - attempts to authenticate with a Kerberos ticket failed with a KRB_AP_ERR_MODIFIED returned. Running the application pool as the user that the SPN was registered to did not change this behaviour.

Microsoft specifies SPNs to include a port number, but IE does not conform to this and never sends a port number in the SPN (Firefox and Chrome follow in this behaviour).

So, is there any way to have multiple independent SPNEGO authenticated services on the same host?

2 Answers
2

Last first: For multiple SPNEGO-authenticated services on the same host, without fiddling with IE registry keys, use different names.

•How does Kerberos authentication work for IIS when there is no SPN for HTTP/canonical.host.name defined using (as checked via setspn -Q)? Clients still request and receive tickets for exactly this SPN.

This is an automatic fallback based on the HOST\boxname SPN , which is created for all computers at domain join time - if the DC doesn't find a match for SPECIFICSERVICE\boxname as requested by the client application, it'll provide a ticket based on HOST\boxname.

Use SETSPN -L boxname to list the SPNs associated with a security principal (user or computer account).

•Out of interest, we tried running the application pools with the identity of the Java service that successfully authenticates. It still did not work as long as the SPN was defined - attempts to authenticate with a Kerberos ticket failed with a KRB_AP_ERR_MODIFIED returned. Running the application pool as the user that the SPN was registered to did not change this behaviour.

The default for IIS 7 is with useAppPoolCredentials=false, and useKernelMode=true ; one or both of these have to be toggled in order for the app pool identity to be used to decode kerberos tickets.

•Microsoft specifies SPNs to include a port number, but IE does not conform to this and never sends a port number in the SPN (Firefox and Chrome follow in this behaviour).

And coming back to the real crux of the matter: when everything else is fixed, IE and others still won't include port numbers by default, so the least-modification solution is simply to run different host headers on the same box.

Note also that due to another IE behaviour (with the same argument against changing all your clients' registry settings), CNAMEs aren't a good choice, use A records instead.

I am not sure I understand your configuration. Is the HTTP/canonical.host.name SPN configured on the service account used for the "Java service"?

You can have multiple services running on the box using different identities. So you can have a service called HTTP/host1.host.name and HTTP/host2.host.name both on the same host. You may register the SPNs involved on the same service account or different service accounts if you so choose.

Requests for HTTP SPN are mapped to objects with the HOST based SPN if the HTTP SPN is not explicitly set anywhere. This mapping happens by the SPNMappings attribute on an object that looks like CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=forest1,DC=local (forest1.local is forest name here) as per http://msdn.microsoft.com/en-us/library/cc220898(v=PROT.13).aspx.

Thanks. I had a good chuckle at the "we fixed it in IE6, but let IE7 and IE8 revert to unfixed unless you set an obscure registry key" behaviour, that's classic Microsoft. Details on failure mode added.
–
themelNov 10 '11 at 20:25

Tristan's answer is spot on. I will just add some further clarification which may help.
–
maweerasNov 11 '11 at 21:26