init_security.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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. from __future__ import annotations
  18. import logging
  19. from importlib import import_module
  20. from flask import redirect, request
  21. from airflow.configuration import conf
  22. from airflow.exceptions import AirflowConfigException, AirflowException
  23. from airflow.www.extensions.init_auth_manager import get_auth_manager
  24. log = logging.getLogger(__name__)
  25. def init_xframe_protection(app):
  26. """
  27. Add X-Frame-Options header.
  28. Use it to avoid click-jacking attacks, by ensuring that their content is not embedded into other sites.
  29. See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
  30. """
  31. x_frame_enabled = conf.getboolean("webserver", "X_FRAME_ENABLED", fallback=True)
  32. if x_frame_enabled:
  33. return
  34. def apply_caching(response):
  35. response.headers["X-Frame-Options"] = "DENY"
  36. return response
  37. app.after_request(apply_caching)
  38. def init_api_experimental_auth(app):
  39. """Load authentication backends."""
  40. auth_backends = "airflow.api.auth.backend.default"
  41. try:
  42. auth_backends = conf.get("api", "auth_backends")
  43. except AirflowConfigException:
  44. pass
  45. app.api_auth = []
  46. try:
  47. for backend in auth_backends.split(","):
  48. auth = import_module(backend.strip())
  49. auth.init_app(app)
  50. app.api_auth.append(auth)
  51. except ImportError as err:
  52. log.critical("Cannot import %s for API authentication due to: %s", backend, err)
  53. raise AirflowException(err)
  54. def init_cache_control(app):
  55. def apply_cache_control(response):
  56. if "Cache-Control" not in response.headers:
  57. response.headers["Cache-Control"] = "no-store"
  58. return response
  59. app.after_request(apply_cache_control)
  60. def init_check_user_active(app):
  61. @app.before_request
  62. def check_user_active():
  63. url_logout = get_auth_manager().get_url_logout()
  64. if request.path == url_logout:
  65. return
  66. if get_auth_manager().is_logged_in() and not get_auth_manager().get_user().is_active:
  67. return redirect(url_logout)