为什么在使用 IIS 反向代理时,Flask 重定向将外部 URL 转换为本地 URL?

huangapple go评论86阅读模式
英文:

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 反向代理时,Flask 重定向将外部 URL 转换为本地 URL?

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="http://localhost:5000/oauth/", NewUrl="/flask/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
英文:

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 反向代理时,Flask 重定向将外部 URL 转换为本地 URL?

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.

答案1

得分: 1

我仔细阅读了您提供的FRT日志。

在第13行,在URL重写之后,请求URL现在是"http://localhost:5000/oauth/",这意味着重写成功。

在第25行:将"Location"响应头设置为"https://login.microsoftonline.com/tenant/oauth2/v2.0/authorize"。这可能是应用程序逻辑的一部分,用于在处理后将客户端重定向到另一个URL。

在第26行:设置"Access-Control-Allow-Origin"头,替换为"false",以确保不会替换现有值。

第27行:重新设置"Location"响应头为"http://www.example.com/tenant/oauth2/v2.0/authorize"。

"Access-Control-Allow-Origin"是CORS(跨源资源共享)头,我认为这是一个跨源请求问题。浏览器通常对网络请求应用同源限制。这些限制将阻止恶意页面在脚本内部进行跨源请求。例如,这意味着通常情况下从https://www.example.com提供的脚本不能向https://login.microsoftonline.com发出请求。

关于跨源资源共享,您可以通过以下链接了解更多信息:

开始使用IIS CORS模块

"Access-Control-Allow-Origin"头是如何工作的

英文:

I carefully read the FRT logs you provided.

On line 13, after the URL rewrite, the request URL is now "http://localhost:5000/oauth/", which means the rewrite was successful.

On line 25: Set the "Location" response header to "https://login.microsoftonline.com/tenant/oauth2/v2.0/authorize". This could be part of application logic that redirects the client to another URL after processing.

On line 26: Set the "Access-Control-Allow-Origin" header , Replace="false", so the existing value will not be replaced.

Line 27: Re-set the "Location" response header to " http://www.example.com/tenant/oauth2/v2.0/authorize ".

"Access-Control-Allow-Origin" is a CORS (Cross-Origin Resource Sharing) header, I think is a cross-origin request issue. Browsers typically apply same-origin restrictions to network requests. These restrictions will prevent malicious pages from making cross-origin requests from within scripts. For example, this means ordinarily a script served from https://www.example.com cannot make a request to https://login.microsoftonline.com.

For cross-origin resource sharing, you can learn more about it through the link below:

Getting started with the IIS CORS Module

How does the 'Access-Control-Allow-Origin' header work

答案2

得分: 0

这是IIS的应用请求路由功能的一部分。在“服务器代理设置”下取消选中“在响应标头中反向重写主机”解决了该问题。

英文:

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 反向代理时,Flask 重定向将外部 URL 转换为本地 URL?

huangapple
  • 本文由 发表于 2023年7月20日 19:13:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76729282.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定