Home > Advanced, C#, WCF > Retrieving the client certificate from an X509Identity in WCF

Retrieving the client certificate from an X509Identity in WCF

Please note: This article is merely a demonstration, I absolutely do not recommend relying on internal classes of the .Net framework in real applications.

WCF can be configured for two mayor modes of security:

  • Transport security
  • Message security
  • (And you actually also have the in between TransportWithMessageCredential, but lets forget this for simplicity …)

In both of these modes WCF can be configured to use X509 certificates as client and service credentials. At the service side, WCF maps these credentials to an IIdentity instance that can be retrieved using the ServiceSecurityContext.

IIdentity identity = ServiceSecurityContext.Current.PrimaryIdentity;

The implementation type of this identity is the internal class  System.IdentityModel.Claims.X509Identity. If we look at this type using reflector we can see the following:

Inspect X509Identity using Reflector

The X509Identity contains the X509 client certificate inside a private variable “certificate”. Using reflection, we can easily retrieve this certificate:

private X509Certificate2 ClientCertificate
{
    get
    {
        try
        {
            IIdentity identity = ServiceSecurityContext.Current.PrimaryIdentity;

            // X509Identity is an internal class, so we cannot directly access it
            Type x509IdentityType = identity.GetType();

            // The certificate is stored inside a private field of this class
            FieldInfo certificateField = x509IdentityType.GetField("certificate", BindingFlags.Instance | BindingFlags.NonPublic);

            return (X509Certificate2)certificateField.GetValue(identity);
        }
        catch (Exception)
        {
            return null;
        }
    }
}

Using this property we can now retrieve the client certificate. This was not that difficult to do? Glimlach

Advertisements
Categories: Advanced, C#, WCF
  1. December 3, 2013 at 09:57

    Just stumbled about this post via Google, and I wanted to add that, according to a comment to this StackOverflow answer: http://stackoverflow.com/a/4992290, you can also access the certificate like this: ((X509CertificateClaimSet) ServiceSecurityContext.Current.AuthorizationContext.ClaimSets[0]).X509Certificat‌​e.

    • pieterderycke
      December 3, 2013 at 11:37

      Thanks for the tip, I was not aware of that 🙂

  1. No trackbacks yet.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: