Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable API response (CORS) headers #13620

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions airflow/api_connexion/openapi/v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ info:
Note that with *Postman*, you can also generate code snippets by selecting a request and clicking on
the **Code** button.

## Enabling CORS

[Cross-origin resource sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
is a browser security feature that restricts HTTP requests that are
initiated from scripts running in the browser.

For details on enabling/configuring CORS, see
[Enabling CORS](https://airflow.apache.org/docs/apache-airflow/stable/security/api.html).

# Authentication

To be able to meet the requirements of many organizations, Airflow supports many authentication methods,
Expand Down
21 changes: 21 additions & 0 deletions airflow/config_templates/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,27 @@
version_added: ~
example: /files/service-account-json
default: ""
- name: access_control_allow_headers
description: |
Used in response to a preflight request to indicate which HTTP
headers can be used when making the actual request. This header is
the server side response to the browser's
Access-Control-Request-Headers header.
type: string
example: ~
default: ""
- name: access_control_allow_methods
description: |
Specifies the method or methods allowed when accessing the resource.
type: string
example: ~
default: ""
- name: access_control_allow_origin
description: |
Indicates whether the response can be shared with requesting code from the given origin.
type: string
example: ~
default: ""
- name: lineage
description: ~
options:
Expand Down
12 changes: 12 additions & 0 deletions airflow/config_templates/default_airflow.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,18 @@ google_oauth2_audience =
# Example: google_key_path = /files/service-account-json
google_key_path =

# Used in response to a preflight request to indicate which HTTP
# headers can be used when making the actual request. This header is
# the server side response to the browser's
# Access-Control-Request-Headers header.
access_control_allow_headers =

# Specifies the method or methods allowed when accessing the resource.
access_control_allow_methods =

# Indicates whether the response can be shared with requesting code from the given origin.
access_control_allow_origin =

[lineage]
# what lineage backend to use
backend =
Expand Down
15 changes: 15 additions & 0 deletions airflow/www/extensions/init_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,20 @@ def init_error_handlers(app: Flask):
app.register_error_handler(404, views.circles)


def set_cors_headers_on_response(response):
ryanahamilton marked this conversation as resolved.
Show resolved Hide resolved
"""Add response headers"""
allow_headers = conf.get('api', 'access_control_allow_headers')
allow_methods = conf.get('api', 'access_control_allow_methods')
allow_origin = conf.get('api', 'access_control_allow_origin')
if allow_headers is not None:
response.headers['Access-Control-Allow-Headers'] = allow_headers
if allow_methods is not None:
response.headers['Access-Control-Allow-Methods'] = allow_methods
if allow_origin is not None:
response.headers['Access-Control-Allow-Origin'] = allow_origin
return response


def init_api_connexion(app: Flask) -> None:
"""Initialize Stable API"""
base_path = '/api/v1'
Expand All @@ -171,6 +185,7 @@ def _handle_api_error(ex):
api_bp = connexion_app.add_api(
specification='v1.yaml', base_path=base_path, validate_responses=True, strict_validation=True
).blueprint
app.after_request(set_cors_headers_on_response)
ashb marked this conversation as resolved.
Show resolved Hide resolved
app.register_error_handler(ProblemException, common_error_handler)
app.extensions['csrf'].exempt(api_bp)

Expand Down
20 changes: 20 additions & 0 deletions docs/apache-airflow/security/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,26 @@ section of ``airflow.cfg``.

Additional options to your auth backend can be configured in ``airflow.cfg``, as a new option.

Enabling CORS
---------------

[Cross-origin resource sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
ryanahamilton marked this conversation as resolved.
Show resolved Hide resolved
is a browser security feature that restricts HTTP requests that are initiated
from scripts running in the browser.

`Access-Control-Allow-Headers`, `Access-Control-Allow-Methods`, and
`Access-Control-Allow-Origin` headers can be added by setting values for
ryanahamilton marked this conversation as resolved.
Show resolved Hide resolved
``access_control_allow_headers``, ``access_control_allow_methods``, and
``access_control_allow_origin`` options in the ``[api]`` section of the
``airflow.cfg`` file.

.. code-block:: ini

[api]
access_control_allow_headers = origin, content-type, accept
access_control_allow_methods = POST, GET, OPTIONS, DELETE
access_control_allow_origin = https://exampleclientapp.com

Page size limit
---------------

Expand Down