10

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.

Janusz Nowak
  • 2,595
  • 1
  • 17
  • 36
Luis Delgado
  • 3,644
  • 4
  • 34
  • 54
  • You can give it a try and tell us :-) – Thomas Apr 06 '18 at 06:22
  • We do support that. Yes, try and let us know. – Suwat Ch Apr 06 '18 at 07:19
  • @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 Mar 01 '19 at 10:50
  • 1
    @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 Mar 20 '19 at 16:39

3 Answers3

5

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; }
}
UnionP
  • 1,251
  • 13
  • 26
  • 1
    `HttpRequest` doesn't seem to have a `GetClientCertificate()` method? – Cocowalla Nov 28 '19 at 17:00
  • The argument you get in an Azure Function method is of type HttpRequestMessage, which has that method. See https://learn.microsoft.com/en-us/sandbox/functions-recipes/http-and-webhooks – UnionP Dec 01 '19 at 20:22
  • 2
    Hmm, yes, I recall it *used* to be, but now you get a `HttpRequest` by default. I seem to seeing a Github issue about this a while back, where a MS employee said this was now their recommendation. I figured out I can get the client cert using `req.HttpContext.Connection.ClientCertificate` – Cocowalla Dec 01 '19 at 20:55
  • 1
    Ah you're correct, in v1 you get an HttpRequestMessage, in v2 you get an HttpRequest. Nice find on how to get the client cert! I'll update my answer – UnionP Dec 02 '19 at 20:26
4

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.

Bruce Chen
  • 18,207
  • 2
  • 21
  • 35
1

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

houss
  • 670
  • 5
  • 9