This is really just a compilation of already known bits of information. But since I had to do this recently and was struggling to get these pieces together, I thought I’ll document all the steps here.
WCF service that uses transport security with an HTTP based binding. The service is self-hosted using a least privilege account. How does that work?
1. Create and install an SSL certificate
The first step is to install an SSL certificate on the target machine. SSL certs are just normal certs with an intended usage of “Server Authentication” (and Key Exchange). You can get them from public CAs like Verisign, an internal CA like Windows Server Certificate Services or generate them yourself using tools like makecert or selfssl (for testing purposes only of course).
The syntax for makecert would be (admin privs required):
makecert -r -pe -n CN=”DNS_NAME_OF_SERVICE” -eku 18.104.22.168.22.214.171.124.1 -ss my -sr localmachine
-sky exchange -sp “Microsoft RSA SChannel Cryptographic Provider” -sy 12
SSL certificates must be installed into the “Personal” certificate store of the machine account (the above makecert command does this).
Afterwards – browse to the certificate using the MMC snap-in and make sure it is marked as valid and the details dialog says “You have a private key that corresponds to this certificate”
2. Map the SSL cert to the WCF listening port
For the next step you need several pieces of data beforehand.
- the port on which your service will listen on
- the thumbprint of the SSL certificate you want to use. Get this data e.g. from the MMC snap-in details dialog. Copy the “Thumbprint” value to a text editor and remove the whitespaces.
- A GUID. Use e.g. the Visual Studio “Create GUID” tool (use the registry format).
On Vista+ you can use the netsh tool to do the mapping (admin privs required):
netsh http add sslcert ipport:0.0.0.0:port certhash=thumbprint appid=GUID
On pre-Vista you can use httpcfg.exe to accomplish the same thing:
httpcfg set ssl /i 0.0.0.0:port /h thumbprint /g “GUID”
You can also use the corresponding tools to view the mapping afterwards.
3. Set an URL ACL for the listening URI
The last step is to set an URI ACL on the listening URI for the service account (see also here). You should use the base address of the service as the entry URI.
Again there are two tools to accomplish this. On Vista use e.g.:
netsh http add urlacl url=https://+:port/Services user=authorityserviceaccount
For pre-Vista use e.g. this tool.
4. Configure the WCF service
The WCF service has to be configured for transport security (and an https protocol moniker) and for the base address you ACLed in step 4. My config looks like this:
<system.serviceModel> <services> <service name="Service" behaviorConfiguration="md"> <endpoint address="SslService" binding="basicHttpBinding" bindingConfiguration="security" contract="IService" /> <host> <baseAddresses> <add baseAddress="https://WcfSelfHost:4433/Services" /> </baseAddresses> </host> </service> </services> <bindings> <basicHttpBinding> <binding name="security"> <security mode="Transport"> <transport clientCredentialType="Basic" /> </security> </binding> </basicHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="md"> <serviceMetadata httpsGetEnabled="true" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>