Suppose there is a WCF service which will be consumed by other parties. The client credential type of this WCF service is configured as certificate. In other word, the WCF consumer must present its client certificate to WCF service for authentication & authorization. This is a typical kind of business –to-business architecture.
By default, WCF provides below options to validate if the incoming client certificate is valid:
More details about this topic, you can refer to below MSDN:
Suppose there are multiple incoming client certificates, let’s say: WCFClient#1, WCFClient#2. Both client certificates can be validated successfully according to above X509 certificate validation policy. Then the problem comes up:
How can we limit only WCFClient#1 can consume the WCF service, and disallow WCFClient#2 to consume the WCF service although WCFClient#2 can be validated successfully?
Or we have multiple WCF services deployed in the same box and will be consumed by multiple other parties who will present their corresponding client certificates, just as below diagram shows:
Then how can we control WCF#1 WCF service can only be consumed by WCFClient#1, and WCF#2 WCF service can be only consumed by WCFClient#2 as well?
Recently I handled several cases that customer were just trying to find a solution to implement above design.
Here I’d like to share a solution to implement this kind of design.
NOTE: One thing I need to mention is: this is one possible solution, but not the only one. So I just share the steps for my specific solution.
The rough idea of this solution is to map the incoming client certificate as a windows account. Then we authorize the access to WCF service based on windows account.
To implement above design, we need to configure IIS and WCF perspective at the same time, and a little coding as well.
NOTE: Here I’d like to use IIS7.5 of Windows Server 2008 R2 as the web server. So all configuration about IIS listed below is about IIS7.5.
1) IIS perspective:
a) For SSL Setting, we need to configure it as below:
“Require SSL + Client Certificates Require”
b) For Authentication setting, we need to enable “Anonymous” authentication and disable all other options.
c) We need to enable iisClientCertificateMappingAuthentication just as below screenshot shows:
So we need to map the incoming client certificate as a windows account. Let’s say the mapped windows account is “mydomain\wcfclientaccount”.
For more details about how to configure client certificate mappings, you can refer to below article:
Configuring Many-to-One Client Certificate Mappings for Internet Information Services (IIS) 7.0 and 7.5
2. WCF Service Perspective:
a) Configure your binding to use Transport Security mode with Certificate client credential type . So the configuration will be just like below:
<transport clientCredentialType=”Certificate” />
b) Apply the same binding configuration to the metadata endpoint. The configuration will just be like below:
<service behaviorConfiguration=”securebehaviour” name=”HelloWorldDemo.Service1″>
<endpoint address=”mex” binding=”basicHttpBinding” bindingConfiguration=”NewBinding0″ name=”mexEndpoint” contract=”IMetadataExchange” />
For more information about this topic, you can refer to below MSDN:
How to: Use Certificate Authentication and Transport Security in WCF Calling from Windows Forms
c) Configure the service behavior as below:
i) Enable service authorization.
ii) Enable “mapClientCertificateToWindowsAccount”
So the configuration will just look as below highlighted.
<serviceMetadata httpGetEnabled=”false” httpsGetEnabled=”true” />
<serviceDebug includeExceptionDetailInFaults=”false” />
<authentication certificateValidationMode=”PeerOrChainTrust” mapClientCertificateToWindowsAccount=”true” />
<serviceAuthorization principalPermissionMode=”UseWindowsGroups” />
More details about mapClientCertificateToWindowsAccount property, you can refer to below MSDN article:
d) Apply PrincipalPermission attribute to that specific method that you want to limit access to, for example:
[PrincipalPermission(SecurityAction.Demand, Name = @”mydomain\wcfclientaccount”)]
public string HelloWorld()
return “Hello World. You have authenticated with account: ” + System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity.Name.ToString();
If you have concern about this kind of hardcoded way, you can also implement it programmatically. The sample code will be like below:
static class PermissionHelper
public static void CheckPermission()
string allowedAccount = System.Configuration.ConfigurationManager.AppSettings[“AllowedWindowsAccount”].ToString();
// We get the allowed windows account who is authorized to call this WCF method from configuration file
PrincipalPermission ppAdmin = new PrincipalPermission(null, allowedAccount);
public class Service1 : IService1
public string helloworld()
//Execute your real logic then
return “Hello World. You have authenticated with account: “ + System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity.Name.ToString();
For more details, you can refer to below article:
3. WCF Client Perspective.
WCF client must present its client certificate by specifying the client certificate using Endpoint behavior just like below:
<clientCertificate findValue=“ AllowedClientCertificate “ storeLocation=“LocalMachine“ x509FindType=“FindBySubjectName“ />
Winston He from AGPC DSI Team