0
votes

Need client certificate based or AAD token based authentication enabled web api hosted in azure app service.

I am migrating one web API from classic cloud service to azure app service. The API supports calls with valid certificates or valid AAD token. Code is given below:

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    ClaimsPrincipal principal;
    var cert = request.GetClientCertificate();
    if (cert != null)
    {
        //authenticate client certificate 
        //Set principal from client certificate 
    }
    else
    {
        //get AAD token 
        //authenticate & set principal 
    }
    return await base.SendAsync(request, cancellationToken);
}

The issue is in App service for certificate based calls request.GetClientCertificate() is returning null instead of X509Certificate2 object. So not able to authenticate certificate based calls.

I have tried below link as well but in that case calling without certificate is not possible as its making required SSL certificate on for whole website. https://docs.microsoft.com/en-us/azure/app-service-web/app-service-web-configure-tls-mutual-auth

1
How you send the request with the certificate to the azure web app? Which kind of the certificate you have used now? Have you upload the certificate to the azure web app?Brando Zhang
What is the purpose of request.GetClientCertificate() ? What is the client and server stack here. Please add these details.Kaushal Kumar Panday
@KaushalKumarPanday : it will validate client on the basis of the thumbprint of that certificate object. msdn.microsoft.com/en-us/library/…ARGHA JOARDER
@BrandoZhang : we generally use .pfx certificate. As this is client certificate we should not install that in our azure app though I tried after installing as well.ARGHA JOARDER

1 Answers

0
votes

There are lot of details missing in your explanation. The shared code snippet is useless.

In Azure App Service, there is a which sits in front of the VM where the application is hosted. When you enable TLS Mutual Auth for your web app, it is enabled for the entire app. Currently there is no option to do it for specific pages or sub-folders.

When the clients accesses the site, the Front-End prompts them for the client certificate. Assuming the client provides the certificate to the Front-End, it then passes this certificate to the back end VM in the form of a host header "X-ARR-ClientCert".

I dont see this being used anywhere in the above code snippet. This is also explained in the article (Azure App Service TLS Mutual Auth) which you have linked in your question:

protected void Page_Load(object sender, EventArgs e)
{
    NameValueCollection headers = base.Request.Headers;
    certHeader = headers["X-ARR-ClientCert"];
    if (!String.IsNullOrEmpty(certHeader))
    {
        try
        {
            byte[] clientCertBytes = Convert.FromBase64String(certHeader);
            certificate = new X509Certificate2(clientCertBytes); 

You need to read the contents X-ARR-ClientCert header and then convert it to a X509Certificate2 object and then run your checks against this.