Application Gateway URL Rewrite Breaking App-Internal Redirects¶
Status: Draft - Blocked
Execution blocked: Application Gateway WAF_v2 SKU required. Cost constraint prevents provisioning in this subscription.
1. Question¶
When Application Gateway rewrites the URL or strips path prefixes before forwarding to App Service, app-internal redirects (HTTP 301/302) that the application generates using the original request URL will reference the wrong base URL. Under what conditions does this create a redirect loop or a broken redirect, and how can the application be made aware of the rewritten URL?
2. Why this matters¶
Application Gateway is commonly used to host multiple App Service apps under a single public endpoint using path-based routing (/api/ → App Service A, /web/ → App Service B). When the gateway strips the path prefix before forwarding (e.g., /api/users becomes /users at App Service), the application may issue redirects to / (root) that become /api/ at the gateway — but the application generates the redirect as https://app.azurewebsites.net/ (internal URL), causing the browser to leave the gateway URL and go directly to the App Service URL. This breaks the routing architecture and may expose the internal App Service URL to clients.
3. Customer symptom¶
"After adding Application Gateway, some pages redirect to the wrong URL" or "Login redirects go to the azurewebsites.net domain instead of our custom domain" or "The app works fine directly but breaks when accessed through Application Gateway."
4. Hypothesis¶
- H1: When Application Gateway rewrites the
Hostheader to the App Service hostname (.azurewebsites.net) and the app generates an absolute redirect usingrequest.host, the redirect uses the App Service hostname instead of the gateway hostname. - H2: Configuring Application Gateway to preserve the
Hostheader (forward the original client hostname) causes App Service to see the gateway hostname and generate correct absolute redirects. - H3: Configuring the app to use relative redirects (instead of absolute) avoids the hostname issue entirely, regardless of Application Gateway host header configuration.
- H4: The
X-Forwarded-Hostheader is forwarded by Application Gateway and can be used by the app to construct the correct redirect URL when the gateway hostname differs from the backend hostname.
5. Environment¶
| Parameter | Value |
|---|---|
| Service | Azure App Service |
| SKU / Plan | P1v3 |
| Region | Korea Central |
| Runtime | Python 3.11 (Flask) |
| OS | Linux |
| Date tested | — |
6. Variables¶
Experiment type: Networking / Routing
Controlled:
- Application Gateway v2 with path-based routing:
/app/*→ App Service - App Service with Flask app that has a login redirect (absolute URL redirect)
- Application Gateway host header override setting (enabled/disabled)
Observed:
Locationheader value in 302 redirect responses- Final URL after redirect chain
- Presence of
X-Forwarded-Hostheader in the request reaching App Service
Scenarios:
- S1: App Gateway with host override (backend hostname) → redirect points to azurewebsites.net
- S2: App Gateway preserving original host header → redirect points to gateway hostname
- S3: App uses
X-Forwarded-Hostto construct redirect → correct URL regardless of host header setting - S4: App uses relative redirects → no hostname issue
7. Instrumentation¶
curl -v https://<agw-hostname>/app/loginto captureLocationheader- App
/headersendpoint to inspect what hostname the app sees (Host,X-Forwarded-Host) - Application Gateway access logs for rewrite rule application
8. Procedure¶
To be defined during execution.
Sketch¶
- Deploy Flask app with
/loginendpoint that redirects tohttps://{request.host}/dashboard(absolute redirect usingrequest.host). - Configure Application Gateway with override host header = App Service hostname.
- S1: Access
/app/loginvia Application Gateway; captureLocationheader; confirm it points to App Service hostname. - S2: Change Application Gateway to preserve original host header; retry; confirm
Locationpoints to gateway hostname. - S3: Update app to use
request.headers.get('X-Forwarded-Host', request.host)for redirect construction; retry with override; confirm correct URL. - S4: Change redirect to relative (
/dashboard); retry all gateway configurations; confirmLocationis always relative.
9. Expected signal¶
- S1:
Location: https://<app>.azurewebsites.net/dashboard(exposes internal URL). - S2:
Location: https://<agw-hostname>/app/dashboardorhttps://<agw-hostname>/dashboarddepending on path handling. - S3: App constructs correct URL from
X-Forwarded-Host;Locationpoints to gateway hostname. - S4:
Location: /dashboard(relative; browser resolves against current base URL, which is the gateway).
10. Results¶
Awaiting execution.
11. Interpretation¶
Awaiting execution.
12. What this proves¶
Awaiting execution.
13. What this does NOT prove¶
Awaiting execution.
14. Support takeaway¶
Awaiting execution.
15. Reproduction notes¶
- Application Gateway host header override is configured per backend setting:
Pick host name from backend targetvs. custom host name vs. preserve client host name. - App Service requires the
Hostheader to match its hostname or configured custom domain to route correctly; using a wrong host may cause 400 errors. - Easy Auth redirect URIs must also account for the gateway hostname when Easy Auth is used behind Application Gateway.