10
votes

Do functions support authorizing access to a Function by using client certificates, in a consumption plan? Something similar to the approach described here? Basically, I'm looking for the Functions runtime to immediately reject connection requests if the caller does not present a valid client certificate, without me having to implement that authorization routine in the code.

3
You can give it a try and tell us :-)Thomas
We do support that. Yes, try and let us know.Suwat Ch
@SuwatCh I have problems accessing a function portal blade as soon as I enable this setting. All works fine until I toggle the client certificate setting - and then the function runtime fails to start and the portal function blade errors. Any thoughts?Nathan
@SuwatCh I am also having issues with this. Once I turn on the client certificate setting any request to my function fails with an HTTP 401 error. I am trying to use a self signed certificate. Do I need to have a certificate that is signed by a CA?John Atwood

3 Answers

4
votes

Based on your requirement, I created my C# HttpTrigger function to check this issue, here is the core code:

if(req.Headers.Contains("X-ARR-ClientCert")) 
{   
    byte[] clientCertBytes = Convert.FromBase64String(req.Headers.GetValues("X-ARR-ClientCert").FirstOrDefault());
    var clientCert = new X509Certificate2(clientCertBytes);
    return req.CreateResponse(HttpStatusCode.OK,"Thumbprint: "+clientCert.Thumbprint);
}
return req.CreateResponse(HttpStatusCode.OK, "Hello world");

For App Service Plan, the function could work as follows:

enter image description here

Per my test, the function could also work as expected under the consumption plan.

You could follow How To Configure TLS Mutual Authentication for Web App or just log into Azure Portal and go to your function app, click "NETWORKIING > SSL" under Platform fetures tab, then enable Incoming client certificate option.

4
votes

Here's the code I came up with, note: this is for Azure Functions v1, when req is an HttpRequestMessage

Caller:

X509Certificate2 clientCert = req.GetClientCertificate();

if (!IsValidClientCertificate(clientCert))
{
    return req.CreateErrorResponse(HttpStatusCode.Unauthorized, "A valid client certificate is not found");
}

For Azure Functions v2, you can get the client certificate from the HttpRequest using req.HttpContext.Connection.ClientCertificate

Basic validation function:

static bool IsValidClientCertificate(X509Certificate2 clientCert)
{
    // check the cert's thumbprint against expected thumbprint
    if (clientCert.Thumbprint != "<expected thumprint>"
    { 
        return false;
    }

    // check that we're within the cert's validity period
    if (DateTime.Now > clientCert.NotAfter || DateTime.Now < clientCert.NotBefore)
    {
        return false;
    }

    // optionally check cert chaining validity
    // if(!clientCert.Verify()) { return false; }
}
1
votes

Yes it does. If I understand you correctly, you want to reject with a 403, any https requests without a client cert

This is how to enable it with Azure CLI

az webapp update --set clientCertEnabled=true --name <app_name> --resource-group <group_name>

Microsoft docs here

You can also do this from the Azure Portal, under Azure Function App => Configuration => General Settings

Enable client Cert