ObjectSharp
Published in

ObjectSharp

Azure Application Gateway: HTTP headers rewrite rules for App Service with AAD authentication

Photo by Max Duzij on Unsplash

As you probably already know, you can use Azure App Service as backend pool for Application Gateway. The general configuration procedure can be found in the Microsoft documentation. This configuration works fine for simple sites, but if your App Service uses Azure Active Directory (AAD) for authentication and authorization, extra steps are required to deal with HTTP redirections related to the AAD authentication flow.

The problem

Azure App Services is configured with AAD authentication like this:

There are two HTTP redirects that happen during the login process.

The first redirect happens when App Service sends un-authenticated user to AAD authorize endpoint to allow user to login and obtain the ID token from AAD. The redirect URL will be like this one:

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id={clieent_id}
&response_type=id_token
&redirect_uri=https%3A%2F%2Fsomeapp.azurewebsites.net%2F.auth%2Flogin%2Faad%2Fcallback
&response_mode=form_post
&scope=openid
&state=12345
&nonce=678910

This URL (also known as the callback URL) contains the address where Azure AD will direct the user’s browser to POST an authentication response after successful login. You can find more details about this process here.

The second redirect happens as a response from the HTTP POST to the authentication callback URL, when App Service redirects the authenticated user to the initially requested app URL.

Below are examples of these redirects extracted from the browser’s development tools.

First redirect (browser accesses address waf.dg20.net that resolves into the Application Gateway frontend IP):

Second redirect:

As you can see, even if the browser tried to access our app using an address assigned to the Application Gateway, after login we will end-up sending HTTP requests directly to App Service, by-passing Application Gateway. This would defeat the whole purpose of putting the app behind the Application Gateway. In the case where App Service is properly locked down and static IP restrictions have been enabled to enforce access only through Application Gateway, the user will potentially see a 403 HTTP error after login:

The solution

The Azure documentation describes this issue here and offers a solution (HTTP headers rewrite) here. Unfortunately, the prescribed procedure doesn’t account for the Azure AD authentication process and only offers a method to ‘fix’ the second redirect. Honestly speaking, this could be considered a “good enough” solution, but it still exposes the App Service native address to the client and will work only if client can hit this address directly after the AAD login process.

The solution below will hide the backend address from the client and will work with the locked down App Service. It will rewrite the “Location” header in the both redirection 302 responses using two rules in the single Rewrite Set on the Application Gateway. Both rules check and rewrite ‘Location’ header in the HTTP response.

1. First redirect rewrite — login redirect to AAD

Condition (If): header “Pattern to match”

(.*)(redirect_uri=https%3A%2F%2F).*\.azurewebsites\.net(.*)$

Action (then): set header value

{http_resp_Location_1}{http_resp_Location_2}{var_host}{http_resp_Location_3}

2. Second redirect rewrite — callback from AAD

(https:\/\/).*\.azurewebsites\.net(.*)$

Action (then): set header value

https://{var_host}{http_resp_Location_2}

This Rewrite Set must be associated with the Application Gateway routing rule to be effective. The set can be used with any routing rule that uses Azure App Service with AAD authentication as a backend, and it can significantly simplify gateway configuration, especially in the scenario where multiple sites are hosted.

Originally published at https://blog.gaikovoi.dev.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store