Securing Azure Function s using certificate authentication.
September 4, 2020 · by · in , , · 3 Comments This article shows how to secure Azure Functions using X509 certificates .

The client is required to send a specific certificate to access the Azure Function

Code: https://github.com/damienbod/AzureFunctionsSecurity Blogs in the series Securing Azure Function s using API Keys.

Securing Azure Functions using Certificate authentication

Setup the Azure Function to require certificates A Dedicated (App Service) plan is used

so that certificates can be set to required for all incoming requests.

The Azure Functions are hosted using an dedicated Azure App Service

Now the Azure App Service can be forced to require certificates

If any certificates are sent, the certificate sent with the HTTP request will get forwarded to the Azure Functions hosted in the Azure App Service .
Using and validating the certificate in an Azure Function The incoming certificate needs to be validated.

The Azure App service forwards the certificate to the X-ARR-ClientCert header

A X509 Certificate 2 can be created from the header value which is a base64 string containing the certificate byte array.
Now the certificate can be validated.
In the example, the Thumbprint is checked and the NotBefore, NotAfter values.
Sadly only self signed certificate s can be used together with Azure (Not chained).

The X509Chain only loads the certificate and not the chain in Azure

This might work with a trusted chain, but I don’t have to money to try this and buy a root certificate for client/server certificate auth.
This is a pity as using chained certificate s would be awesome for this type of security.
Chained certificates created from a non-trusted root certificate works outside Azure and other hosts.
[FunctionName(“RandomStringCertAuth”)] public IActionResult RandomStringCertAuth( [HttpTrigger(AuthorizationLevel.
Anonymous, “get”, Route = null)] HttpRequest req) { _log.
LogInformation(“C# HTTP trigger RandomString processed a request.”); StringValues cert; if (req.
Headers.
TryGetValue(“X-ARR-ClientCert”, out cert )) { byte[] clientCertBytes = Convert.
FromBase64String(cert[0]); X509Certificate2 clientCert = new X509Certificate2(clientCertBytes); // Validate Thumbprint if (clientCert.
Thumbprint != “5726F1DDBC5BA5986A21BDFCBA1D88C74C8EDE90”) { return new BadRequestObjectResult(“A valid client certificate is not used”); } // Validate NotBefore and NotAfter if (DateTime.
Compare(DateTime.
UtcNow, clientCert.
NotBefore) < 0 || DateTime. Compare(DateTime. UtcNow, clientCert. NotAfter) > 0) { return new BadRequestObjectResult(“client certificate not in alllowed time interval”); } // Add further validation of certificate as required.
return new OkObjectResult(GetEncodedRandomString()); } return new BadRequestObjectResult(“A valid client certificate is not found”); } Sending a request using a HttpClient A client can now use the Azure Function API.
We will use a.

NET Core console application which uses the HttpClient

The X509Certificate2 certificate is added to the ClientCertificates of the handler and the request can be sent.
// Test Azure deployment private static async Task CallAzureDeployedAPI(string url, .

X509Certificate2 clientCertificate) { var handler = new HttpClientHandler(); handler

ClientCertificates.
Add(clientCertificate); var client = new HttpClient(handler); var request = new HttpRequestMessage() { RequestUri = new Uri(url), Method = HttpMethod.
Get, }; var response = await client.
SendAsync(request); if (response.
IsSuccessStatusCode) { var responseContent = await response.
Content.
ReadAsStringAsync(); Console.
WriteLine(responseContent); return responseContent; } throw new ApplicationException($”Status code: {response.
StatusCode}, Error: {response.
ReasonPhrase}”); } Local testing using a HttpClient and local Azure Function If testing locally, the certificate will not get added to the HTTP X-ARR-ClientCert header.

We can add this directly in the HttpClient so that we can test locally

This is not required when the Azure Function is deployed to Azure

// Local dev private static async Task CallApiXARRClientCertHeader(string url, X509Certificate2 clientCertificate) { try { var handler = new HttpClientHandler(); handler.
ClientCertificates.
Add(clientCertificate); var client = new HttpClient(handler); var request = new HttpRequestMessage() { RequestUri = new Uri(url), Method = HttpMethod.
Get, }; request.
Headers.
Add(“X-ARR-ClientCert”, Convert.
ToBase64String(clientCertificate.
RawData)); var response = await client.
SendAsync(request); if (response.
IsSuccessStatusCode) { var responseContent = await response.
Content.
ReadAsStringAsync(); return responseContent; } throw new ApplicationException($”Status code: {response.
StatusCode}, Error: {response.
ReasonPhrase}”); } catch (Exception e) { throw new ApplicationException($”Exception {e}”); } } Testing the Function If we start the application using the correct client certificate, .

The random string will be returned from the Azure Function

If we start the application using the incorrect client certificate or no certiifcate, an exception will be thrown in the HttpClient.
Links: https://docs.microsoft.com/en-us/azure/azure-functions/security-concepts https://docs.microsoft.com/en-us/aspnet/core/security/authentication/certauth https://damienbod.com/2019/06/13/certificate-authentication-in-asp-net-core-3-0/ https://damienbod.com/2019/09/07/using-certificate-authentication-with-ihttpclientfactory-and-httpclient/ https://github.com/dotnet/aspnetcore/blob/master/src/Security/Authentication/Certificate/src/CertificateAuthenticationHandler.cs https://stackoverflow.com/questions/27307322/verify-server-certificate-against-self-signed-certificate-authority https://stackoverflow.com/questions/24107374/ssl-certificate-not-in-x509store-when-uploaded-to-azure-website#34719216 https://docs.microsoft.com/en-us/azure/app-service/app-service-web-configure-tls-mutual-auth#access-client-certificate Share this:.
Twitter.
Facebook.
Like this:.
Like Loading.
Related.
Tags: Authn, Azure, azure app service, Azure Function, certificate, tls, x509 3 comments.
cocowalla · September 4, 2020 – 09:49 · Reply→ As well as the `X-ARR-ClientCert` header, you can also access the certificate from the HTTP request object: `request.
HttpContext.
Connection.
ClientCertificate` I seem to recall it also works like: `request.
HttpContext.
Features.
Get().
ClientCertificate` · September 4, 2020 – 10:12 · Reply→ Hi Cocowalla thanks, I’ll try this again, this didn’t work when I deployed it to Azure using functions, works with ASP.
ENT Core, but I will try it and again and validate.
Dew Drop – September 4, 2020 (#3269) | Morning Dew · September 4, 2020 – 12:04 · Reply→ […] Securing Azure Functions using certificate authentication (Damien Bowden) […].
Leave a Reply Cancel reply.
Enter your comment here.
Fill in your details below or click an icon to log in:.
Email (Address never made public) Name Website You are commenting using your WordPress.com account.
( Log Out /   ) You are commenting using your Google account.
( Log Out /   ) You are commenting using your Twitter account.
( Log Out /   ) You are commenting using your Facebook account.
( Log Out /   ) Cancel Connecting to %s Notify me of new comments via email.
Notify me of new posts via email.
This site uses Akismet to reduce spam.
Learn how your comment data is processed.
← Using Digital Signatures to check integrity of cipher texts in ASP.
NET Core Razor Pages Categories Select Category.
NET.
NET Core angular AngularJS AOP App Service ASP.
NET Core ASPNET5 Azure Azure functions Azure Key Vault Deployment devops Docker dotnet Elasticsearch Enterprise Library Entity Framework git javascript jQuery Logging Lucene Mobile Monitoring MVC MVVM Nest NLog NoSQL NuGet OAuth2 OData Protobuf Security Semantic Logging Serverless SignalR SLAB SQL SQLite TopHeaderMenu Typescript UI Uncategorized Unity Validation Web Windows 8 Apps WiX WPF Post to %d bloggers like this:.

Leave a Comment on Securing Azure Functions using certificate authentication

Leave a Reply

Your email address will not be published. Required fields are marked *