Azure Functions and App Service Authentication with Auth0 and other OpenID Connect providers
Tags: azure, serverless, security, tutorial
Published: 2020-07-23 16:34:04

---
title: "Azure Functions and App Service Authentication with Auth0 and other OpenID Connect providers"
published: true
description: How to integrate Auth0 and other OpenID Connect compliant providers with Azure Functions and Azure App Service.
tags: azure, serverless, security, tutorial
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/fewvuf2kgsrllz884j1v.png
canonical_url: https://anthonychu.ca/post/azure-functions-app-service-openid-connect-auth0/
---

Azure Functions and Azure App Service recently added [integration with OpenID Connect (OIDC) providers](https://docs.microsoft.com/azure/app-service/configure-authentication-provider-openid-connect). We can now use any [OpenId Connect](https://openid.net/connect/) compliant provider to authenticate users in our apps.

In this article, we'll look at how to configure Auth0 with Azure Functions. The same steps can be used to configure any other OIDC provider and can also be applied to Azure App Service.

## Overview

To integrate an OpenID Connect provider with Azure Functions, we need to follow these steps:

1. Obtain a client id and secret plus other config settings from the OIDC provider.
1. Create an authentication config file in our app and add the relevant information from the OIDC provider to the file.
1. Supply the client secret in an app setting.
1. Enable file-based authentication configuration in the app.

<!--more-->

## Create an app in Auth0

[Auth0](https://auth0.com/) is a popular identity service. It supports login via many social identities as well as with app-specific accounts.

Instead of configuring our function app with social logins like Google or creating a custom username/password database solution, we can rely on Auth0 to manage all that for us and we simply integrate our app with Auth0 using OpenID Connect.

The first thing we need to do to get started is create a free Auth0 account. Then we create an app in Auth0 of type "Regular Web Application".

![Create an app](https://dev-to-uploads.s3.amazonaws.com/i/gbg2q6ibvsdds9wh12nu.png)

When the app is created, note the client id and secret.

![id and secret](https://dev-to-uploads.s3.amazonaws.com/i/02anp05bs9sfn8w0n7o6.png)

> Note: We need to create a function app in Azure before proceeding with the following steps. Auth0 is going to need to use the app name in some configurations.

In the *Application URIs* section, fill in these settings:

* *Application Login URI* - `https://<app-name>.azurewebsites.net/.auth/login/auth0`
* *Allowed Callback URLs* - `https://<app-name>.azurewebsites.net/.auth/login/auth0/callback`
* *Allowed Logout URLs* - `https://<app-name>.azurewebsites.net/.auth/logout`

![URLs](https://dev-to-uploads.s3.amazonaws.com/i/iz889nzjuhl7qd0yitis.png)

The most important setting is the *Allowed Callback URLs*, which tells Auth0 about the callback URL that the function app authentication will use.

Note that each URL has a segment with the value `auth0`. This needs to match the name we give the OIDC provider in the configuration file that we'll cover next.

Click *Save Changes*. Then click on the subtle *Show Advanced Settings* link.

![advanced settings](https://dev-to-uploads.s3.amazonaws.com/i/6jpipdw26wp8176othpa.png)

In the Endpoints tab, note the *OpenID Configuration URL*.

![well known configs](https://dev-to-uploads.s3.amazonaws.com/i/dtvzvj8xiwbgeot1j1m7.png)

## Create an authentication config file

Currently, OpenID Connect providers can only be enabled in Azure Functions or App Service using a new file-based configuration. Multiple providers can be configured in the same app.

The config file must be located in the root of the function app. We'll create one named *auth.json*.

Then we place this content in the file:

```json
{
  "platform": {
    "enabled": true
  },
  "globalValidation": {
    "redirectToProvider": "auth0",
    "unauthenticatedClientAction": "RedirectToLoginPage"
  },
  "identityProviders": {
    "openIdConnectProviders": {
      "auth0": {
        "registration": {
          "clientId": "<auth0_client_id>",
          "clientCredential": {
            "secretSettingName": "AUTH0_CLIENT_SECRET"
          },
          "openIdConnectConfiguration": {
            "wellKnownOpenIdConfiguration": "https://<auth0_tenant_name>.auth0.com/.well-known/openid-configuration"
          }
        },
        "login": {
          "nameClaimType": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
          "scope": [ "openid", "profile", "email" ],
          "loginParameterNames": []
        }
      }
    }
  },
  "login": {
    "tokenStore": {
      "enabled": true
    }
  }
}
```

Replace the values of `clientId` with the Auth0 client id, and `wellKnownOpenIdConfiguration` with the OpenID configuration URL from Auth0.

We've also specified some scopes so that we can obtain profile and email information from the customer.

Now that the auth file is added to the app, we publish the app to Azure.

Note that we didn't put the client secret into the file. That's because we don't want to commit it to source control. Instead, we provide the app setting name (`AUTH0_CLIENT_SECRET`) that we'll use to store that value in Azure.

## Add a client secret app setting

In the function app's *Configuration* page, create an app setting named `AUTH0_CLIENT_SECRET`. In the value, paste in the Auth0 client secret.

![app settings](https://dev-to-uploads.s3.amazonaws.com/i/h7c9cta1ddum47445gnr.png)

## Enable file-based auth configuration

The last step we have to take is enable the use of our new file-based auth config. There's no UI for this yet. We can use an Azure CLI command to do it.

```bash
az rest --method put --url https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/$APP_NAME/config/authsettings?api-version=2018-02-01 --body "{\"properties\":{\"enabled\":\"true\",\"isAuthFromFile\":\"true\",\"authFilePath\":\"auth.json\"}}"
```

The above command updates the app's `authsettings` properties with the following values:

* `enabled` = `true`
* `isAuthFromFile` = `true`
* `authFilePath` = `auth.json`

## Test it out

Now when we try to access the function app in the browser, we're redirected to Auth0. We can create a new account to log in.

![Sign up](https://dev-to-uploads.s3.amazonaws.com/i/fewvuf2kgsrllz884j1v.png)

In an HTTP triggered function, the authenticated user's information can be obtained from the `x-ms-client-principal` header. We need to convert it from base64 encoded JSON.

```javascript
module.exports = async function (context, req) {
  const buffer = Buffer.from(req.headers["x-ms-client-principal"], "base64");
  const user = JSON.parse(buffer.toString("ascii"));
  
  const email = user.claims.find(c => c.typ === "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress").val;
  const nickname = user.claims.find(c => c.typ === "nickname").val;
  
  context.res = {
    status: 200,
    body: `Hello ${nickname} [${email}]`
  };
};
```

This function returns:

```
Hello anthony [anthony@anthonychu.ca]
```

## Resources

* [Configure your App Service or Azure Functions app to login using an OpenID Connect provider (Preview)](https://docs.microsoft.com/azure/app-service/configure-authentication-provider-openid-connect)
* [How to use Azure App Service Authentication](https://docs.microsoft.com/azure/app-service/app-service-authentication-how-to)