0

I'm working on a project which requires delegation in a double-hop scenario. We have a desktop client, connecting to a WCF service using a net.tcp binding, connecting to a SQL database on another server. Our goal is to use the user's credentials to access the SQL database.

Both the WCF service and SQL database are running under the same domain user, which has delegation enabled for the SQL database. The instructions here have been followed, with no success.

Now, some details recorded in our logs: The login used on the SQL database appears as the user the WCF service is running under, and uses Kerberos. The login used on the WCF server appears as the client's user, but uses NTLM. Using either [OperationBehavior(Impersonation = ImpersonationOption.Allowed)] or using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate()) results in commands being run as the client, on the WCF server. This leads me to believe impersonation is working fine.

So, what could be causing the first hop to fall back to NTLM? We suspect it's a SPN issue, but we've registered the SPNs of both the WCF service and SQL service to the shared domain user. Also, as per the instructions listed above, we've set the SQL service as trusted for delegation on the domain user.

We've used EndpointIdentity.CreateSpnIdentity on the WCF service to set the SPN, and this is the SPN we've registered to the domain user.

Any suggestions? Thanks in advance!

Edit: We've found something that may have been an issue - We had not used EndpointIdentity.CreateSpnIdentity on the client. After setting this we receive the error “call to SSPI failed” with an inner exception of “target principle name is incorrect”. But the SPN we've set in the client and the server match, and both match the hostname of the service. If we set both the client and the server SPN to something completely different, or if the client's specified SPN does not match the server's SPN, authentication falls back to NTLM as it did before. We've done research into the error, but cannot find its cause. Any suggestions?

We've also performed packet captures of both cases - falling back to NTLM and when we receive the "call to SSPI failed" error. In both cases, similar packets are sent and received until, on one, NTLM is mentioned. On the other, a "TURN CHANNEL" packet is sent from the client to the server. The packets contain nothing human readable except the IP address of the server until either NTLM is mentioned, and the username and computer names are sent, or the "TURN CHANNEL" packet is sent, which contains what appears to be the SPN, and possibly the hostname. There doesn't appear to be any human readable error codes or error messages. Any suggestions on what to look for in the packets?

1 Answers1

0

We found our error - the client was creating the connection using the IP address of the server. After switching the IP to a fully qualified domain name, the first hop consistently authenticates using Kerberos.

The IP address resolves to the same string we used in both SPNs, but I suppose the client checks if the connection string matches the portion of the SPN following the slash before performing any other checks.

We tested our results using both Network Service and our domain user, and as long as the SPN was registered to the computer or user respectively, there were no issues.

Hopefully this answer will save others some time and hassle!


Additional Note: While this enabled Kerberos authentication for all connections, we later discovered that this was unnecessary in our situation. Part of our connection to the database was not inside the impersonation using block, which was causing the table read to fail. We have since removed all delegation and SPN related code, and the database connection continued to work correctly. Our first hop is using NTLM. We're not exactly sure how the credentials are being used at the SQL server, as our connection appears to be exactly what is described as the double hop scenario, which should require Kerberos and delegation, but it's hard to argue with what's working. I suspect it may have something to do with the note located under delegation in this document:

When a client authenticates to the front-end service using a user name and password that correspond to a Windows account on the back-end service, the front-end service can authenticate to the back-end service by reusing the client’s user name and password. This is a particularly powerful form of identity flow, because passing user name and password to the back-end service enables the back-end service to perform impersonation, but it does not constitute delegation because Kerberos is not used. Active Directory controls on delegation do not apply to user name and password authentication.

If anyone has any other suggestions for the reason it's working, I'd love to hear them. However, I don't feel it's worth opening another question for.