Configuring Auth0 as an OpenID Connect provider for your Azure App Service
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.
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.
- Application Type: Regular Web Application
- Allowed Callback URL: https://YOUR_SITE.azurewebsites.net/.auth/login/auth0/callback
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.
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:
{
"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:
{
"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
.
"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.
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": {
"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": {
"nameClaimType": "name",
"scope": [
"openid",
"profile",
"email"
],
"loginParameterNames": [
]
}
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.
"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:
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 emailx-ms-client-principal-id
: containing the user's IDx-ms-client-principal-idp
: the name of the provider used by the current userx-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:
✅ 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.