From 40e5f44a83c83bb6dc8d92982dc7060670074f8d Mon Sep 17 00:00:00 2001 From: Ash Berlin-Taylor Date: Thu, 24 Apr 2025 14:55:33 +0100 Subject: [PATCH] Fix infinite redirect caused by mistakenly setting token cookie as secure `api/ssl_cert` has a default value of "" so `has_option` is always returning true, so we have to find in a slightly more complex way of telling if this setting is turned on. I have also updated the Simple security manager to look at X-Forwarded-Proto so that if there is a reverse proxy in front (and if Airflow is configured to trust that) then it sets the secure flag --- airflow-core/docs/core-concepts/auth-manager/index.rst | 2 +- .../api_fastapi/auth/managers/simple/routes/login.py | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/airflow-core/docs/core-concepts/auth-manager/index.rst b/airflow-core/docs/core-concepts/auth-manager/index.rst index 417bad407db1f..365295296eb00 100644 --- a/airflow-core/docs/core-concepts/auth-manager/index.rst +++ b/airflow-core/docs/core-concepts/auth-manager/index.rst @@ -148,7 +148,7 @@ delete the cookie. response = RedirectResponse(url="/") - secure = conf.has_option("api", "ssl_cert") + secure = bool(conf.get("api", "ssl_cert", fallack="")) response.set_cookie(COOKIE_NAME_JWT_TOKEN, token, secure=secure) return response diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/routes/login.py b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/routes/login.py index c901692d8f9c8..82875ceb1239c 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/routes/login.py +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/routes/login.py @@ -17,7 +17,7 @@ from __future__ import annotations -from fastapi import status +from fastapi import Request, status from starlette.responses import RedirectResponse from airflow.api_fastapi.auth.managers.base_auth_manager import COOKIE_NAME_JWT_TOKEN @@ -57,10 +57,14 @@ def create_token_all_admins() -> LoginResponse: status_code=status.HTTP_307_TEMPORARY_REDIRECT, responses=create_openapi_http_exception_doc([status.HTTP_403_FORBIDDEN]), ) -def login_all_admins() -> RedirectResponse: +def login_all_admins(request: Request) -> RedirectResponse: """Login the user with no credentials.""" response = RedirectResponse(url=conf.get("api", "base_url", fallback="/")) - secure = conf.has_option("api", "ssl_cert") + + # The default config has this as an empty string, so we can't use `has_option`. + # And look at the request info (needs `--proxy-headers` flag to api-server) + secure = request.base_url.scheme == "https" or bool(conf.get("api", "ssl_cert", fallback="")) + response.set_cookie( COOKIE_NAME_JWT_TOKEN, SimpleAuthManagerLogin.create_token_all_admins(),