Skip to content

Commit 59d592f

Browse files
gschuurmanGlenn Schuurman
and
Glenn Schuurman
authored
Add back ProxyFix Middleware for flask app builder (apache#49942)
* Add back ProxyFix Middleware for flask app builder Fixes Issues apache#49781 apache#49705 Add back the Removed ProxyFix Middleware to allow Oauth2 authentication when using a reverse proxy like nginx or traefik. When not using proxyFix the redirect_url incorectly gets set to http:// instead of the expected https://, This breaks many authentication flows, especially azure, which does not allow http:// redirect_urls for anything other than localhost. Help is needed with adjusting the configuration from webserver to api-server. * Add config documentation to fab provider Add the original proxy_fix documentation back into the FAB provider package and update the section to match fab instead of websever. * Use correct versioning scheme for provider * Fix typo in import * Bypass missing extention test --------- Co-authored-by: Glenn Schuurman <[email protected]>
1 parent dd9df35 commit 59d592f

File tree

5 files changed

+138
-0
lines changed

5 files changed

+138
-0
lines changed

airflow-core/tests/unit/always/test_project_structure.py

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ def test_providers_modules_should_have_tests(self):
138138
"providers/fab/tests/unit/fab/www/extensions/test_init_security.py",
139139
"providers/fab/tests/unit/fab/www/extensions/test_init_session.py",
140140
"providers/fab/tests/unit/fab/www/extensions/test_init_views.py",
141+
"providers/fab/tests/unit/fab/www/extensions/test_init_wsgi_middlewares.py",
141142
"providers/fab/tests/unit/fab/www/security/test_permissions.py",
142143
"providers/fab/tests/unit/fab/www/test_airflow_flask_app.py",
143144
"providers/fab/tests/unit/fab/www/test_app.py",

providers/fab/provider.yaml

+52
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,58 @@ config:
119119
type: integer
120120
example: ~
121121
default: "43200"
122+
enable_proxy_fix:
123+
description: |
124+
Enable werkzeug ``ProxyFix`` middleware for reverse proxy
125+
version_added: 2.1.0
126+
type: boolean
127+
example: ~
128+
default: "False"
129+
proxy_fix_x_for:
130+
description: |
131+
Number of values to trust for ``X-Forwarded-For``.
132+
See `Werkzeug: X-Forwarded-For Proxy Fix
133+
<https://werkzeug.palletsprojects.com/en/2.3.x/middleware/proxy_fix/>`__ for more details.
134+
version_added: 2.1.0
135+
type: integer
136+
example: ~
137+
default: "1"
138+
proxy_fix_x_proto:
139+
description: |
140+
Number of values to trust for ``X-Forwarded-Proto``.
141+
See `Werkzeug: X-Forwarded-For Proxy Fix
142+
<https://werkzeug.palletsprojects.com/en/2.3.x/middleware/proxy_fix/>`__ for more details.
143+
version_added: 2.1.0
144+
type: integer
145+
example: ~
146+
default: "1"
147+
proxy_fix_x_host:
148+
description: |
149+
Number of values to trust for ``X-Forwarded-Host``.
150+
See `Werkzeug: X-Forwarded-For Proxy Fix
151+
<https://werkzeug.palletsprojects.com/en/2.3.x/middleware/proxy_fix/>`__ for more details.
152+
version_added: 2.1.0
153+
type: integer
154+
example: ~
155+
default: "1"
156+
proxy_fix_x_port:
157+
description: |
158+
Number of values to trust for ``X-Forwarded-Port``.
159+
See `Werkzeug: X-Forwarded-For Proxy Fix
160+
<https://werkzeug.palletsprojects.com/en/2.3.x/middleware/proxy_fix/>`__ for more details.
161+
version_added: 2.1.0
162+
type: integer
163+
example: ~
164+
default: "1"
165+
proxy_fix_x_prefix:
166+
description: |
167+
Number of values to trust for ``X-Forwarded-Prefix``.
168+
See `Werkzeug: X-Forwarded-For Proxy Fix
169+
<https://werkzeug.palletsprojects.com/en/2.3.x/middleware/proxy_fix/>`__ for more details.
170+
version_added: 2.1.0
171+
type: integer
172+
example: ~
173+
default: "1"
122174

123175
auth-managers:
124176
- airflow.providers.fab.auth_manager.fab_auth_manager.FabAuthManager

providers/fab/src/airflow/providers/fab/get_provider_info.py

+42
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,48 @@ def get_provider_info():
7979
"example": None,
8080
"default": "43200",
8181
},
82+
"enable_proxy_fix": {
83+
"description": "Enable werkzeug ``ProxyFix`` middleware for reverse proxy\n",
84+
"version_added": "2.1.0",
85+
"type": "boolean",
86+
"example": None,
87+
"default": "False",
88+
},
89+
"proxy_fix_x_for": {
90+
"description": "Number of values to trust for ``X-Forwarded-For``.\nSee `Werkzeug: X-Forwarded-For Proxy Fix\n<https://werkzeug.palletsprojects.com/en/2.3.x/middleware/proxy_fix/>`__ for more details.\n",
91+
"version_added": "2.1.0",
92+
"type": "integer",
93+
"example": None,
94+
"default": "1",
95+
},
96+
"proxy_fix_x_proto": {
97+
"description": "Number of values to trust for ``X-Forwarded-Proto``.\nSee `Werkzeug: X-Forwarded-For Proxy Fix\n<https://werkzeug.palletsprojects.com/en/2.3.x/middleware/proxy_fix/>`__ for more details.\n",
98+
"version_added": "2.1.0",
99+
"type": "integer",
100+
"example": None,
101+
"default": "1",
102+
},
103+
"proxy_fix_x_host": {
104+
"description": "Number of values to trust for ``X-Forwarded-Host``.\nSee `Werkzeug: X-Forwarded-For Proxy Fix\n<https://werkzeug.palletsprojects.com/en/2.3.x/middleware/proxy_fix/>`__ for more details.\n",
105+
"version_added": "2.1.0",
106+
"type": "integer",
107+
"example": None,
108+
"default": "1",
109+
},
110+
"proxy_fix_x_port": {
111+
"description": "Number of values to trust for ``X-Forwarded-Port``.\nSee `Werkzeug: X-Forwarded-For Proxy Fix\n<https://werkzeug.palletsprojects.com/en/2.3.x/middleware/proxy_fix/>`__ for more details.\n",
112+
"version_added": "2.1.0",
113+
"type": "integer",
114+
"example": None,
115+
"default": "1",
116+
},
117+
"proxy_fix_x_prefix": {
118+
"description": "Number of values to trust for ``X-Forwarded-Prefix``.\nSee `Werkzeug: X-Forwarded-For Proxy Fix\n<https://werkzeug.palletsprojects.com/en/2.3.x/middleware/proxy_fix/>`__ for more details.\n",
119+
"version_added": "2.1.0",
120+
"type": "integer",
121+
"example": None,
122+
"default": "1",
123+
},
82124
},
83125
}
84126
},

providers/fab/src/airflow/providers/fab/www/app.py

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
init_error_handlers,
4242
init_plugins,
4343
)
44+
from airflow.providers.fab.www.extensions.init_wsgi_middlewares import init_wsgi_middleware
4445
from airflow.providers.fab.www.utils import get_session_lifetime_config
4546

4647
app: Flask | None = None
@@ -103,6 +104,7 @@ def create_app(enable_plugins: bool):
103104
init_jinja_globals(flask_app, enable_plugins=enable_plugins)
104105
init_xframe_protection(flask_app)
105106
init_airflow_session_interface(flask_app)
107+
init_wsgi_middleware(flask_app)
106108
return flask_app
107109

108110

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
from __future__ import annotations
19+
20+
from typing import TYPE_CHECKING
21+
22+
from werkzeug.middleware.proxy_fix import ProxyFix
23+
24+
from airflow.configuration import conf
25+
26+
if TYPE_CHECKING:
27+
from flask import Flask
28+
29+
30+
def init_wsgi_middleware(flask_app: Flask) -> None:
31+
"""Handle X-Forwarded-* headers and base_url support."""
32+
# Apply ProxyFix middleware
33+
if conf.getboolean("fab", "ENABLE_PROXY_FIX"):
34+
flask_app.wsgi_app = ProxyFix( # type: ignore
35+
flask_app.wsgi_app,
36+
x_for=conf.getint("fab", "PROXY_FIX_X_FOR", fallback=1),
37+
x_proto=conf.getint("fab", "PROXY_FIX_X_PROTO", fallback=1),
38+
x_host=conf.getint("fab", "PROXY_FIX_X_HOST", fallback=1),
39+
x_port=conf.getint("fab", "PROXY_FIX_X_PORT", fallback=1),
40+
x_prefix=conf.getint("fab", "PROXY_FIX_X_PREFIX", fallback=1),
41+
)

0 commit comments

Comments
 (0)