Certificate based Authentication and WCF (Mode independent)

My third approach for restricting trust when using client certificates works for transport and message security. Furthermore it does not involve any OS level configuration.

WCF has a piece of plumbing called the Service Authorization Manager. The SAM gets called on every incoming request and at this point the claim sets are already populated. In the issuer claim set of the client, you can find the thumbprint of the issuing CA (you can also find the thumbprint of the end certificate of course).

With that information you can apply the same logic as in the certificate validator I showed earlier.

Writing a SAM involves deriving from a class called ServiceAuthorizationManager and implementing the CheckAccessCore method. The logic looks like this:

protected override bool CheckAccessCore(OperationContext operationContext)
{
    string[] trustedThumbprints = GetTrustedThumbprints();
    string[] thumbprints;

    if (ValidationMode == ValidationMode.EndCertificate)
    {
        thumbprints = new string[] {
            GetEndCertificateThumbprint(operationContext) };
    }
    else
    {
        thumbprints = GetIssuerThumbprints(operationContext);
    }

    return IsTrusted(thumbprints, trustedThumbprints);
}

To get the thumbprint from the claim set, you simply search for a thumbprint identity claim. One thing to note here is that the thumbprint gets stored as a byte[]. You can use the BitConverter class to convert that into a string, e.g.

private string GetEndCertificateThumbprint(OperationContext operationContext)
{
    foreach (ClaimSet set in 
operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets) { foreach (Claim claim in set.FindClaims(ClaimTypes.Thumbprint, Rights.Identity)) { string tb = BitConverter.ToString((byte[])claim.Resource); tb = tb.Replace("-", ""); return tb; } } throw new Exception("No thumbprint claim found"); }
The last step is to register the SAM in the serviceAuthorization behavior:
<behaviors>
  <serviceBehaviors>
    <behavior name="behavior">
      <serviceAuthorization serviceAuthorizationManagerType="type" />
    </behavior>
  </serviceBehaviors>
</behaviors>

Be aware that the SAM gets called on every request. Make sure the logic is as inexpensive as possible.

In the download you can find a SAM base class which follows the same design pattern as the certificate validator. Just override the GetTrustedThumbprints method.

CertAM.zip (51.86 KB)

 

This entry was posted in WCF. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s