The default behavior for an Application Gateway with App Service instance in the backend pool is that the Host header is overridden to match the Web App’s default hostname: *.azurewebsites.net. This is caused by the “Use for App Service” and “Pick host name from backend address” configuration options on the Application Gateway. These requests arrive at the App Service frontend and route to the destination based upon matching Host header.
While these settings make initial configuration easier, they do have a few consequences:
- Backend URL exposed when there is a redirect or URL that is built in application logic
- Application behavior issues when the client’s hostname or HTTP protocol do not match what arrives at the backend Web App
- Failed authentication when the auth provider sees the backend Host header, rather than the custom domain accessed by the user
- ARR Affinity is broken to the backend instances, because the Host header is mismatched
Example of App Logic Issue
- Create a new Web App and delete the default homepage
- Go to the Kudu site and create these two files in the /site/wwwroot/ directory
- default.aspx : https://pastebin.com/mu1TwDjW
- default.aspx.cs : https://pastebin.com/RXvXBYqG
- Test the site directly and view the URLs that are built in application logic based upon the Host header which arrived
After introducing an Application Gateway frontend with a custom hostname listener, the above application output remains the same, because the logic is only aware of the headers which arrived at the backend.
Solution
There are two options to address this behavior:
- Code level, change the logic that builds URLs or reads the Host header to use a static hostname or read from x-original-host
- Configuration level, pass the desired custom hostname all the way through to the backend Web App
When passing the desired hostname to the backend Web App, we can target the same pool, but the HTTP Settings needs to be reconfigured to force the desired hostname. Note that this hostname must first be validated on the target App Service.
Validated hostname:
Overall architecture:
HTTP Setting:
Results with the desired hostname processed by app logic:
Above we can see that my app logic is now processing my desired hostname, and the internal *.azurewebsites.net URL is never exposed to my client. This issue manifests itself many different ways, but the solution in general is the same.
How to validate custom hostname on backend Web App without impacting current Routing
In the above scenario your custom domain is already resolving to the Application Gateway. There is a simple way to validate the hostname on the backend Web App without impacting the current routing, using DNS TXT record: