WCF security provides confidentiality and integrity for message exchanges. We support both symmetric and asymmetric cryptography implementation. In this blog, I like to discuss WCF security using X509 (asymmetric) specifically. By the end of this blog, you should be able to answer the following questions.
1) How do I assign the client or service X509 for WCF to use?
2) How do I define the validation or authentication for the incoming X509 and what is the default?
3) How do WCF enable protocol transition (map to windows account)?
I assume you have had experiences with WCF writing its services or clients. It is beneficial if you are familiar with X509 and PKI (Public Key Infrastructure) how they are used to secure communications.
It turns out the answers for the above questions depend on the bindings and configurations being used. Hence, before jumping into the answer, I would like to discuss briefly what WCF bindings utilizing X509 are available.
WCF enables three different bindings using X509 namely Https, SSL over Tcp and Message Security.
- Https is one of the most common protocols adopted by internet security. Generally, it is intended for server authentication using TLS/SSL protocol to exchange server’s X509. WCF enables this thru its standard http bindings with Transport as well as TransportWithMessageCredential as a security mode and, for custom binding, HttpsTranportBindingElement. In addition, the protocol allows client to send its X509 to identify itself to the server. If Transport security mode is used, the client’s x509 is transmitted via schannel (sspi). If TransportWithMessageCredential security mode is used, the client’s x509 is transmitted in the soap message (http payload).
Note: schannel is one of the security service providers (ssp) shipped with the operating system that provides SSL/TLS implementation.
- SSL over Tcp uses SSL protocol over Tcp. WCF enables this thru its standard NetTcpBinding with Transport and TransportWithMessageCredential security modes and, for custom binding, SslStreamSecurityBindingElement. Similar to Https above, client could send its X509 to identify itself to the server. If Transport security mode is used, the client’s x509 is transmitted via schannel (sspi). If TransportWithMessageCredential security mode is used, the client’s x509 is transmitted in the soap message.
- Message Security uses WS-* protocol to secure messages. WCF enables this thru its various standard bindings with Message security mode and, for custom binding, SecurityBindingElement.CreateXXXBindingElement. It supports both SSL and MutualCertificate protocol. The difference is how client obtains the server’s X509. Client could send its X509 to identify itself to the server.
Now let’s try to answer the question.
How to assign the server X509
For Https, it is done using httpcfg tool (httpcfg set ssl). If it is webhosted, one could also specify the server’s X509 using IIS manager UI (under properties->Directory Security).
For SSL over Tcp and Message Security, it is specified thru ServiceHost.Credentials.ServiceCertificate property.
How to assign the client X509
Client’s X509 is always specified thru ChannelFactory.Credentials.ClientCertificate property. There are a few catches for Https. First, the client’s X509 issuer must be in Trusted root (belong to IssuerListInfoEx); otherwise, it will never be transmitted to server (403 forbidden). Second, when specifying server X509 using httpcfg tool, make sure “-f 2” passed as parameter indicating negotiate client X509. For web-hosted, you will also have to turn on ‘require client certificate’ checkbox in iis manager (directory security tab).
How to provide authentication for incoming client’s X509
For Https, the server always validates incoming client’s X509 using chain trust (chained to trusted root).
For SSL over Tcp and Message Security, it is specified at ServiceHost.Credentials.ClientCertificate.Authentication property; by default, the X509 must chain to trusted root. This also applies when Https is used but client’s X509 is transmitted using soap message (i.e. TransportWithMessageCredentials mode).
How to provide authentication for incoming server’s X509
For Https, it is specified at System.Net.ServicePointManager.ServerCertificateValidationCallback; by default, the X509 must chain to trusted root and Dns name must match with server address.
For SSL over Tcp and Message Security, it is specified at channelFactory.Credentials.ServiceCertificate.Authentication property; by default, the X509 must chain to trusted root.
Map Client’s X509 to Windows Account
WCF provides a knob to enable the mapping (ServiceHost.Credentials.ClientCertificate.Authentication.MapClientCertificateToWindowsAccount); by default, false (no mapping). WCF supports two ways for mapping X509 to Windows Account; namely schannel mapping and UPN mapping.
- Schannel mapping: this is only supported if TLS/SSL protocol is used. In short, if X509 is associated with the account at AD (Active Directory), schannel will simply map to that account. Otherwise, schannel enforces NT_AUTH policy on the certificate and use S4U over UPN SubjAltNames or some heuristic derivation of X509 issuer name.
- UPN mapping: if Scahnnel mapping is not available, WCF will enforce NT_AUTH on X509 and manually perform S4U logon over UPN SubjAltNames. Note: in Vista, WCF uses the latest LsaLogon api that supports X509-Windows mapping.
For Https, this varies between self-hosted and web-hosted scenario. For self-hosted, although TLS/SSL was used, there was limitation in OM causing Schannel mapping to be unavailable. Therefore, only UPN mapping is used. This will likely be addressed in the future CLR version. For web-hosted, IIS provides a client X509 mapping feature. If the X509 is configured for mapping, the mapped Windows account will be used; otherwise, UPN mapping. BTW, if Https is used but client’s X509 is transmitted thru soap message (i.e. TransportWithMessageCredentials mode), only UPN mapping is applied.
For SSL over Tcp, although SSL was used, there was limitation in OM causing Schannel mapping to be unavailable. Therefore, only UPN mapping is used. This will likely be addressed in the future CLR version.
For Message Security, if TLS/SSL binding is used, WCF will try Schannel mapping then UPN mapping. For other binding (i.e. MutualCertificate), only UPN mapping is applied.
The tables below briefly summarize what we just discussed.
Server X509 provision
Client X509 provision
For self host, use httpcfg tool. For webhost, use IIS manager.
SSL over Tcp
Server X509 authentication
Client X509 authentication
Client X509 Windows Mapping
For selfhost, Upn Mapping. For webhost, IIS mapping then Upn Mapping
If SSL is used, try schannel mapping then Upn Mapping.