Search code examples
pythonflaskreverse-proxyiis-10

Why is flask redirect turning an external URL into a local URL while using reverse proxy in IIS?


Just for some background, I have been trying to set up Azure AD OAuth authentication using flask dance. The actual issue I'm having is when redirecting to the authorization URL, flask is not redirecting as I would expect it to.

I've tried using a simple redirect like this:

@oauth_blueprint.route('/')
def route_oauth():
    return flask.redirect('https://login.microsoftonline.com/tenant/oauth2/v2.0/authorize')

Now, if I access the page directly at localhost:5000/oauth then it works as expected and redirects me to the URL.

However, our web application is set up using a reverse proxy. The flask application is accessed at www.example.com/flask/xxx which returns the corresponding page at localhost:5000/xxx. So if I go to www.example.com/flask/oauth then I should get the same page as localhost:5000/oauth.

So the problem is when I go to www.example.com/flask/oauth the redirect does not work correctly. Instead of taking me to https://login.microsoftonline.com/tenant/oauth2/v2.0/authorize, I instead get redirected to www.example.com/tenant/oauth2/v2.0/authorize. I can't make sense of this as the URL is clearly not a relative URL.

In case it's relevant, we are using URL Rewrite in IIS. There is a simple rewrite rule which matches any URL starting with flask/. This has worked fine for all our other pages.

This is what the rule looks like in IIS: IIS Inbound Rule

I've tried using FRT to trace the rewrite. Below is the output I got. It changes to the undesired URL at line 27 but I don't understand why.

| No. | EventName                      | Details                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | Time         |
| --- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| 1.  | GENERAL_REQUEST_START          | SiteId="2", AppPoolId="App", ConnId="1610613017", RawConnId="1610613017", RequestURL="http://www.example.com/flask/oauth/", RequestVerb="GET"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 12:35:02.963 |
| 2.  | GENERAL_ENDPOINT_INFORMATION   | RemoteAddress="::1", RemotePort="64068", LocalAddress="::1", LocalPort="81"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | 12:35:02.963 |
| 3.  | GENERAL_REQUEST_HEADERS        | Headers="Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,\*/\*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9 Host: www.example.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.82 sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Microsoft Edge";v="114" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Upgrade-Insecure-Requests: 1 Sec-Fetch-Site: none Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document " | 12:35:02.963 |
| 4.  | GENERAL_GET_URL_METADATA       | PhysicalPath="", AccessPerms="513"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | 12:35:02.963 |
| 5.  | HANDLER_CHANGED                | OldHandlerName="", NewHandlerName="StaticFile", NewHandlerModules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule", NewHandlerScriptProcessor="", NewHandlerType=""                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | 12:35:02.963 |
| 6.  | URL_REWRITE_START              | RequestURL="/flask/oauth/", Scope="Distributed", Type="Inbound"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | 12:35:02.963 |
| 7.  | RULE_EVALUATION_START          | RuleName="Flask", RequestURL="flask/oauth/", QueryString="", PatternSyntax="Regex", StopProcessing="true", RelativePath="/"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | 12:35:02.963 |
| 8.  | PATTERN_MATCH                  | Pattern="^flask/(.\*)", Input="flask/oauth/", Negate="false", Matched="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | 12:35:02.963 |
| 9.  | REWRITE_ACTION                 | Substitution="http://localhost:5000/{R:1}", RewriteURL="http://localhost:5000/oauth/", AppendQueryString="true", LogRewrittenURL="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | 12:35:02.963 |
| 10. | RULE_EVALUATION_END            | RuleName="Flask", RequestURL="http://localhost:5000/oauth/", QueryString="", StopProcessing="true", Succeeded="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | 12:35:02.963 |
| 11. | GENERAL_SET_REQUEST_HEADER     | HeaderName="X-Original-URL", HeaderValue="/flask/oauth/", Replace="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | 12:35:02.963 |
| 12. | URL_CHANGED                    | OldUrl="/flask/oauth/", NewUrl="http://localhost:5000/oauth/"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 12:35:02.963 |
| 13. | URL_REWRITE_END                | RequestURL="http://localhost:5000/oauth/"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | 12:35:02.963 |
| 14. | USER_SET                       | AuthType="", UserName="", SupportsIsInRole="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | 12:35:02.963 |
| 15. | HANDLER_CHANGED                | OldHandlerName="StaticFile", NewHandlerName="ApplicationRequestRoutingHandler", NewHandlerModules="ApplicationRequestRouting", NewHandlerScriptProcessor="", NewHandlerType=""                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | 12:35:02.963 |
| 16. | GENERAL_SET_REQUEST_HEADER     | HeaderName="Max-Forwards", HeaderValue="10", Replace="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | 12:35:02.963 |
| 17. | GENERAL_SET_REQUEST_HEADER     | HeaderName="X-Forwarded-For", HeaderValue="[::1]", Replace="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | 12:35:02.963 |
| 18. | GENERAL_SET_REQUEST_HEADER     | HeaderName="X-ARR-SSL", HeaderValue="", Replace="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | 12:35:02.963 |
| 19. | GENERAL_SET_REQUEST_HEADER     | HeaderName="X-ARR-ClientCert", HeaderValue="", Replace="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 12:35:02.963 |
| 20. | GENERAL_SET_REQUEST_HEADER     | HeaderName="X-ARR-LOG-ID", HeaderValue="0f2e2610-c6a8-4412-be80-431075354701", Replace="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 12:35:02.963 |
| 21. | GENERAL_SET_REQUEST_HEADER     | HeaderName="Connection", HeaderValue="", Replace="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | 12:35:02.963 |
| 22. | URL_CHANGED                    | OldUrl="http://localhost:5000/oauth/", NewUrl="/flask/oauth/"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 12:35:02.963 |
| 23. | GENERAL_SET_RESPONSE_HEADER    | HeaderName="Content-Length", HeaderValue="371", Replace="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | 12:35:02.963 |
| 24. | GENERAL_SET_RESPONSE_HEADER    | HeaderName="Content-Type", HeaderValue="text/html; charset=utf-8", Replace="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | 12:35:02.963 |
| 25. | GENERAL_SET_RESPONSE_HEADER    | HeaderName="Location", HeaderValue="https://login.microsoftonline.com/tenant/oauth2/v2.0/authorize", Replace="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | 12:35:02.963 |
| 26. | GENERAL_SET_RESPONSE_HEADER    | HeaderName="Access-Control-Allow-Origin", HeaderValue="/..", Replace="false"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | 12:35:02.963 |
| 27. | GENERAL_SET_RESPONSE_HEADER    | HeaderName="Location", HeaderValue="http://www.example.com/tenant/oauth2/v2.0/authorize", Replace="true"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | 12:35:02.963 |
| 28. | GENERAL_SET_RESPONSE_HEADER    | HeaderName="X-Powered-By", HeaderValue="ARR/3.0", Replace="false"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | 12:35:02.963 |
| 29. | GENERAL_NOT_SEND_CUSTOM_ERROR  | Reason="SETSTATUS_SUCCESS"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | 12:35:02.963 |
| 30. | GENERAL_FLUSH_RESPONSE_START   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | 12:35:02.963 |
| 31. | GENERAL_RESPONSE_HEADERS       | Headers="Content-Type: text/html; charset=utf-8 Location: http://www.example.com/tenant/oauth2/v2.0/authorize Server: Microsoft-IIS/10.0 Access-Control-Allow-Origin: /.. X-Powered-By: ARR/3.0 "                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | 12:35:02.963 |
| 32. | GENERAL_RESPONSE_ENTITY_BUFFER | Buffer="<!doctype html> <html lang=en> <title>Redirecting...</title> <h1>Redirecting...</h1> <p>You should be redirected automatically to the target URL: <a href="https://login.microsoftonline.com/tenant/oauth2/v2.0/authorize">https://login.microsoftonline.com/tenant/oauth2/v2.0/authorize</a>. If not, click the link. "                                                                                                                                                                                                                                                                                                                                       | 12:35:02.963 |
| 33. | GENERAL_FLUSH_RESPONSE_END     | BytesSent="666", ErrorCode="The operation completed successfully. (0x0)"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | 12:35:02.963 |
| 34. | GENERAL_REQUEST_END            | BytesSent="666", BytesReceived="1028", HttpStatus="302", HttpSubStatus="0"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | 12:35:02.963 |

I'd really appreciate any help on this issue. I'm happy to provide any more details if necessary. Thank you.


Solution

  • It turns out that this is a feature of Application Request Routing for IIS. Unchecking "Reverse rewrite host in response headers" under "Server Proxy Settings" resolved the issue.

    IIS Application Request Routing Configuration