Setting up Application Gateway with an App Service that uses Azure Active Directory Authentication
This blog post is going to guide you through setting up an Azure Application Gateway in front of an Azure App Service that uses Azure Active Directory authentication and a custom domain. The default steps for setting up an Azure Application Gateway in front of an App Service with App Service Authentication will result in the reply url directing the end user browser to the *.azurewebsites.net hostname instead of the custom domain that routes through the Application Gateway. These steps will correctly redirect the client browser to the custom domain that routes through the Application Gateway after authenticating. These steps ensure the reply url is the custom domain and you can still monitor requests through the Application Gateway. This applies to any Azure App Service Authentication. I will show you specifically how to us Azure Active Directory authentication in this walkthrough.
This walkthrough assumes that you have an Azure Application Gateway set up with a public IP address. We will use this Application Gateway to be the front door for our application. You do not need to have any additional setup on the Application Gateway beyond it being created.
You should also have an Azure App Service set up for your application. We will go through setting up the App Service first.
Preparing the App Service
We are going to need to prepare the App Service to accept requests on the custom domain that routes through the Application Gateway. For this, we need to first add the custom domain on the App Service. You can either follow the regular guide to configure a custom domain (https://docs.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-custom-domain) or you can use awverify records to avoid adjusting the domain’s actual records (https://docs.microsoft.com/en-us/azure/app-service/app-service-custom-domain-name-migrate).
In my example, I have set up an App Service named AppGatewayAADApp and I have configured a custom domain starting with “appgateway” on this App Service.
Azure App Service Authentication requires HTTPS so we need to configure an SSL certificate for our custom domain. I have uploaded a private certificate for my custom domain and configured an SNI-based SSL binding for this domain as well.
Next, we need to set up Azure Active Directory authentication using the “Authentication / Authorization” feature on the App Service. I am going to use the “Express” mode for setting up my Azure Active Directory application and specify a new application to create. For more information on configuring Azure Active Directory authentication, please see this document: https://docs.microsoft.com/en-us/azure/app-service/app-service-mobile-how-to-configure-active-directory-authentication. After setting up the authentication options, be sure to click “Save” on this blade. I am also setting my application to require unauthenticated requests to be redirected to log in with Azure Active Directory.
Finally, we need to configure our Azure Active Directory application to have the proper reply URLs, that way when we log in through the custom domain, the Azure Active Directory application does not throw errors. From the “Authentication / Authorization” overview, click on the “Azure Active Directory” option. In there, click on “Manage Application”. This will take you to the Azure Active Directory configuration.
On the Azure Active Directory application configuration blade, click on “Reply URLs” in the “Settings” blade. This will open the various reply URLs that the application is able to use to send an authenticated user back to your application. If you configured your custom domain before setting up Azure Active Directory authentication, both your *.azurewebsites.net and custom domain URLs should be configured for the reply URLs. If your custom domain is not there, be sure to set up the reply URL as https://<custom domain>/.auth/login/aad/callback
You should now be able to test out signing in to your App Service. Go to either the custom domain or the *.azurewebsites.net hostname to ensure you can sign in.
In the above configuration, we have set our full application to use Azure Active Directory authentication. This is going to require us to configure our Application Gateway probe later to allow a 401 response from our application. If you are not comfortable with this, there are alternative ways to allow for an unauthenticated health check page on your App Service while requiring the rest of it to be behind Azure Active Directory authentication. I will provide a link to another blog post at the end of this one to document one such workaround.
Setting up the Application Gateway
Now that our App Service is configured how we want it, we can focus on configuring our Application Gateway. We are going to use PowerShell for this, as the required settings we need to set are only available in PowerShell for now.
First, before configuring the Application Gateway, ensure that you change your custom domain from pointing to the App Service to pointing to the Application Gateway's public IP or DNS name. This change is done in your DNS registrar.
The typical guide for setting up an App Service behind an existing Application Gateway is here: https://docs.microsoft.com/en-us/azure/application-gateway/application-gateway-web-app-powershell#configure-a-web-app-behind-an-existing-application-gateway. At this point, open PowerShell, but we will use a different script below instead. Since Azure Active Directory authentication requires HTTPS, I have adjusted the default script to accommodate this.
The key part of the script that has been adjusted is with the backend HTTP settings. The default configuration for the backend HTTP setting uses “-PickHostNameFromBackendAddress”, which would use the *.azurewebsites.net hostname when connecting to the backend App Service. When that configuration is in place, authentication goes towards the *.azurewebsites.net hostname instead of the custom domain, causing authenticated users to be directed towards the *.azurewebsites.net hostname and bypassing the Application Gateway. By instead using the ‘-HostName "<enter your custom domain i.e www.contoso.com>"’ configuration for the backend HTTP settings, we are sending requests to the App Service using the custom domain, allowing authentication to occur on the custom domain and keeping users going through this custom domain. This way, after authentication, users are still routing through your Application Gateway and to the App Service.
Here is the script that you will need to adjust:
# FQDN of the web app $webappFQDN = "<enter your webapp FQDN i.e mywebsite.azurewebsites.net>" # Retrieve an existing application gateway $gw = Get-AzureRmApplicationGateway -Name AppGatewayAAD -ResourceGroupName AppGatewayAADBlog # Define the status codes to match for the probe $match=New-AzureRmApplicationGatewayProbeHealthResponseMatch -StatusCode 200-401 # Add a new probe to the application gateway Add-AzureRmApplicationGatewayProbeConfig -name AppGatewayAADProbe -ApplicationGateway $gw -Protocol Https -Path / -Interval 30 -Timeout 120 -UnhealthyThreshold 3 -PickHostNameFromBackendHttpSettings -Match $match # Retrieve the newly added probe $probe = Get-AzureRmApplicationGatewayProbeConfig -name AppGatewayAADProbe -ApplicationGateway $gw # Configure an existing backend http settings Set-AzureRmApplicationGatewayBackendHttpSettings -Name appGatewayBackendHttpSettings -ApplicationGateway $gw -HostName "<enter your custom domain i.e www.contoso.com>" -Port 443 -Protocol https -CookieBasedAffinity Disabled -RequestTimeout 30 -Probe $probe # Add the web app to the backend pool Set-AzureRmApplicationGatewayBackendAddressPool -Name appGatewayBackendPool -ApplicationGateway $gw -BackendFqdns $webappFQDN # Update the application gateway Set-AzureRmApplicationGateway -ApplicationGateway $gw
Once you run the script, you are all set! Browse to your custom domain over HTTPS, login using Azure Active Directory, and you’ll be authenticated to your site over the custom domain. Now you can use Azure Active Directory in an App Service and still have the requests route through your Application Gateway.
If you run into any issues after setting everything up, be sure to check the backend health of the Application Gateway. The backend pool we set up should be marked as “Healthy”. If not, then your app is returning a response outside of your probe’s range.
Also, test going to your App Service over the *.azurewebsites.net URL. If you can login using Azure Active Directory authentication to this address, then the issue isn’t on the App Service side.
Optional Configuration Using URL Authorization Rules
If you are not comfortable with having your Application Gateway health probe accept a 401 response code, you can use alternative configurations to have part of your App Service unauthenticated. One such method is discussed in another blog post here: https://blogs.msdn.microsoft.com/waws/2017/11/21/setting-up-application-gateway-with-an-app-service-that-uses-azure-active-directory-authentication-and-url-authorization-rules/.