Eugene Karachkovsky Eugene Karachkovsky - 1 month ago 221
C# Question

IdentityServer3 pass Request.ClientCertificate from client request context

I have following configuration: some web app with hosted on iis with "Require SSL" parameter set. Also i have authentication service based on IdentityServer3.

I need to pass Request.ClientCertificate.SerialNumber from my web app to IdentityServer in authentication flow.

Here's part of my client config:

Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = n =>
{
// if signing in, send certificate parameters
if(n.ProtocolMessage.RequestType == OpenIdConnectRequestType.AuthenticationRequest)
{
// here i would like to get client certificate
var req = n.OwinContext.Request;

// and pass it's serial number to IdentityServer someway
n.ProtocolMessage.AcrValues = req.ClientCertificate.SerialNumber
}

return Task.FromResult(0);
},
}


Is it possible? How can i get current request's ClientCertificate?

Answer

Finally, i've got this working:

Notifications = new OpenIdConnectAuthenticationNotifications
{
    RedirectToIdentityProvider = n =>
    {
        // if signing in, send certificate parameters
        if(n.ProtocolMessage.RequestType == OpenIdConnectRequestType.AuthenticationRequest)
        {
            var RequestContext = n.OwinContext.Environment["System.Web.Routing.RequestContext"] as System.Web.Routing.RequestContext;
            if (RequestContext != null)
            {
                var clientCert = RequestContext.HttpContext.Request.ClientCertificate;

                // if client authenticated with certificate then extract certificate info and pass it to identity server
                if (!string.IsNullOrEmpty(clientCert.SerialNumber))
                {
                    var sn = clientCert.SerialNumber.Replace("-", "");

                    // Acr on IdentityServer side explodes by spaces. To prevent splitting values with spaces made some replaces
                    n.ProtocolMessage.AcrValues = "cert:" + sn + " " + clientCert.Subject.Replace(" ","_*_").Replace(",_*_"," ");
                }
            }
        }

        return Task.FromResult(0);
    },
}
Comments