Monday, April 20, 2015

SPNs: What they are and how to work them

I've been wrangling WCF's security modes for a few days now, and I think I finally understand what this whole SPN thing is about. It took some research and experimentation to figure this out, so it might be helpful to others.

SPN stands for Service Principal Name. It's kind of like a user account in that it's stored in Active Directory and that it is used to verify an identity, but the identity that SPNs verify is that of a service (an application whose traffic is secured with Kerberos). Each SPN is bound to a specific user account, so it can only be used by applications running as that user. The interesting thing about that fact is that machine accounts are users too, so any application running as the System or NetworkService account can use the SPNs set aside for the machine.

SPN names are strings of the form "service/place". "service" is unique to your application, but you can name it anything you want, so long as your client is expecting it. "place" is a disambiguator, in case you want multiple instances of the service running on the network. (It seems only one machine can use an SPN at a time.) "place" can also be blank as long as there's a slash in the SPN name.

To create and manage SPNs for the domain, you'll need to use the "setspn" tool that comes with any domain-joinable version of Windows. Type setspn username to get a list of all the SPNs usable by that user. (You'll need to be running as an elevated domain admin to use most of setspn's features.) If you run that for a machine account, you'll see several SPNs that were automatically generated for the computer, including the often-referenced host/machine.example.com one.

To add a new SPN for a user, do something like this:

setspn -S AwesomeServer/TheOneAndOnly HostingUser

HostingUser will then be able to open a Kerberos-secured WCF endpoint for AwesomeServer. The user can certainly be a machine account, but if your application will always be running as an account that can access the computer's SPNs, you might as well just have it use the auto-generated host/machine one.

Opening the WCF endpoint is easy. Just create a new SpnEndpointIdentity, pass it the SPN name, and pass that identity object to CreateChannel, make sure to enable transport security, and you're secure!

No comments:

Post a Comment