Configuring Auth0 as an OpenID Connect provider for your Azure App Service

SD

Sandrino Di Mattia / July 27, 2020

6 min read––– views

Introduction#

For a very long time the Azure App Service made it very easy to authenticate users using Azure AD and a handful of social providers through the flip of a switch. But what hasn't been possible is the ability for customers to integrate other providers like Auth0 or Identity Server in this same way.

Azure App Service Authentication

This is now changing with the introduction of OpenID Connect providers (in preview), making it trivial to secure your site with any OpenID Connect provider, including Auth0. Let's take a look.

Configuring Auth0#

First we'll configure our Azure App Service as a client in Auth0.

Create client in Auth0

Note that the Allowed Callback URL needs to point to your Azure App Service. This is where the user will be redirected to after they have signed in.

Configuring your Azure App Service#

Enabling file-based configuration#

During the preview of the OpenID Connect provider you'll be required to use file-based configuration. In this mode, the authentication configuration lives in your repository and no longer requires the use of Azure Resource Manager (or the Azure Portal).

The easiest way to enable file-based configuration is through the Azure Resource Explorer.

Enabling file-based configuration

Select your subscription, then open the Resource Group in which your App Service is located and finally navigate to the /config/authsettings of your site.

Then you'll need to replace the properties of your settings with the following:

/config/authsettings/properties
{
  "enabled": true,
  "isAuthFromFile": "true",
  "authFilePath": "auth.json"
}

More documentation on file-based configuration can be found in the Azure documentation.

Configuring the provider#

Now that we've moved to file-based configuration we can create a JSON file in the repository of our web application in which we configure all of the authentication settings for our site. Here's an example:

auth.json
{
  "platform": {
    "enabled": true
  },
  "globalValidation": {
    "requireAuthentication": true,
    "unauthenticatedClientAction": "RedirectToLoginPage",
    "redirectToProvider": "auth0",
    "excludedPaths": ["/"]
  },
  "identityProviders": {
    "openIdConnectProviders": {
      "auth0": {
        "enabled": true,
        "registration": {
          "clientId": "28HzCsoC2YTAHRW4QWOYDRL35lcJKXb5",
          "clientCredential": {
            "secretSettingName": "AUTH0_CLIENT_SECRET"
          },
          "openIdConnectConfiguration": {
            "wellKnownOpenIdConfiguration": "https://sandrino.auth0.com/.well-known/openid-configuration"
          }
        },
        "login": {
          "nameClaimType": "name",
          "scope": ["openid", "profile", "email"]
        }
      }
    },
    "login": {
      "tokenStore": {
        "enabled": true
      },
      "preserveUrlFragmentsForLogins": true
    },
    "httpSettings": {
      "requireHttps": true
    }
  }
}

Let's go over some of these settings. So for starters, we'll configure a new OpenID Connect provider named auth0.

provider
"openIdConnectProviders": {
"auth0": {
... } }

You'll notice in the registration section we have the clientId configured, which is your Auth0 Client ID. Then for the clientCredential we're not storing the actual secret in this file. Instead, we need to create an Application Setting with the same name which is where we'll need to enter the Auth0 Client Secret.

Configuration Settings

The wellKnownOpenIdConfiguration field will need to contain the URL to the OpenID Configuration metadata of your Auth0 account. Simply replace the domain with your own Auth0 Domain (or your Auth0 Custom Domain). The App Service will then read the metadata document and extract all the information it needs to interact with Auth0.

registration
"registration": {
"clientId": "28HzCsoC2YTAHRW4QWOYDRL35lcJKXb5",
"clientCredential": {
"secretSettingName": "AUTH0_CLIENT_SECRET"
}, "openIdConnectConfiguration": {
"wellKnownOpenIdConfiguration": "https://sandrino.auth0.com/.well-known/openid-configuration"
} }

We can then also define additional scopes in the login section.

login
"login": {
"nameClaimType": "name",
"scope": [ "openid", "profile", "email" ], "loginParameterNames": [ ] }
The loginParameterNames field does not seem to be working as expected, none of the configured parameters are forwarded to the provider. This might be a temporary issue during the preview.

And finally in the globalValidation section we can configure how our site needs to behave. In this section we've configured that authentication is required, except for the home page. And when a user needs to sign in, they need to be redirected to the auth0 provider.

globalConfiguration
"globalValidation": {
  "requireAuthentication": true,
  "unauthenticatedClientAction": "RedirectToLoginPage",
  "redirectToProvider": "auth0",
  "excludedPaths": [
    "/"
  ]
}

End Result#

Once you've pushed these changes to your repository and a new version of your site is deployed, changes will immediately go into effect. Here's an example of what happens when users hit a protected route:

Signing in

You can also redirect your users to a direct link to initiate the login process:

https://your-website.azurewebsites.net/.auth/login/auth0

Accessing user information#

When the request is authenticated, the App Service will pas several headers to the application which you can then parse to access the user information. These headers include:

  • x-ms-client-principal-name: containing the user's name or email
  • x-ms-client-principal-id: containing the user's ID
  • x-ms-client-principal-idp: the name of the provider used by the current user
  • x-ms-client-principal: a Base64 encoded objected containing all of the information received from the provider

Your application will need to parse these headers, but if you're using .NET 4.6 or higher this information will be available in the ClaimsPrincipal

More information about user claims can be found in the Azure documentation.

Troubleshooting#

I've had several issues testing the preview of the new OpenID Connect provider. For starters, due to how the paths for file-based configuration are generated everything documented above does not work on Linux. Only Windows deployments seem to work correctly.

2020-07-27T07:39:44.832821691Z File name: '/home\site\wwwroot\auth.json'
2020-07-27T07:39:44.833166908Z    at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
2020-07-27T07:39:44.833174708Z    at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)
2020-07-27T07:39:44.833179208Z    at System.IO.FileStream.OpenHandle(FileMode mode, FileShare share, FileOptions options)
2020-07-27T07:39:44.833183509Z    at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
2020-07-27T07:39:44.833187909Z    at System.IO.StreamReader.ValidateArgsAndOpenPath(String path, Encoding encoding, Int32 bufferSize)
2020-07-27T07:39:44.833192209Z    at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks)
2020-07-27T07:39:44.833196509Z    at System.IO.File.InternalReadAllText(String path, Encoding encoding)
2020-07-27T07:39:44.833200609Z    at System.IO.File.ReadAllText(String path)
2020-07-27T07:39:44.833204710Z    at Microsoft.Azure.AppService.Middleware.Modules.ConfigFactory.GenerateMiddlewareModuleConfig(INameResolver resolver) in /EasyAuth/Microsoft.Azure.AppService.Middleware.Modules/ConfigFactory.cs:line 80

In case you run into any issue, make sure to configure your App Service logs to Verbose and look at the Log stream which will contain the necessary information to troubleshoot any issues which might come up:

Troubleshooting

✅ Success!#

Even though this feature is still in preview and there are some small hiccups, it's clear that the App Service Authentication features can make it super easy to add authentication to your applications without requiring any complex code or SDK in your actual codebase.

A demo application is available in which you can test the flow end to end: https://oidc-auth0-demo.azurewebsites.net/. The source of the application is availabe on GitHub.

More documentation on how to use and configure the OpenID Connect provider is available on the Azure documentation site.

Discuss on Twitter