tjedynak commented on issue #56614:
URL: https://github.com/apache/airflow/issues/56614#issuecomment-3553169093

   @vincbeck
   
   I’m hitting what looks like the same problem when using 
**KeycloakAuthManager** with Keycloak Authorization Services.
   
   ### Environment
   
   * Apache Airflow: **3.1.1**
   * Webserver/API: FastAPI + Uvicorn (default in 3.1.x)
   * Auth manager: **KeycloakAuthManager** (OIDC)
   * Keycloak:
   
     * OIDC client: `airflow` with **Authorization** enabled
     * Policy enforcement mode: `Enforcing`
     * Resources / Scopes / Policies / Permissions defined for DAGs and Assets
   * Access token lifespan for client `airflow` set to **2 minutes** in Keycloak
   
   ### What I observe
   
   1. I log in to the Airflow UI via Keycloak SSO.
   2. Everything works fine initially:
   
      * I can open the main dashboard
      * View DAG details
      * Trigger DAGs, etc.
   3. After **~2 minutes** (exactly the client’s access-token TTL), I go back 
to the home/dashboard (UI “Home” button), which triggers calls like:
   
      * `GET /ui/dashboard/historical_metrics_data?...`
      * `GET /api/v2/assets/events?...`
      * sometimes also `GET /api/v2/dagTags?...`
   4. At this point the UI fails with **500 Internal Server Error** and the 
logs show:
   
   ```text
   airflow.exceptions.AirflowException: Unexpected error: 401 - 
{"error":"invalid_grant","error_description":"Invalid bearer token"}
     File ".../airflow/api_fastapi/core_api/security.py", line 141, in inner
       _requires_access(
     File ".../airflow/api_fastapi/core_api/security.py", line 491, in 
_requires_access
       if not is_authorized_callback():
     File ".../airflow/api_fastapi/core_api/security.py", line 142, in <lambda>
       is_authorized_callback=lambda: get_auth_manager().is_authorized_dag(
     File 
".../airflow/providers/keycloak/auth_manager/keycloak_auth_manager.py", line 
165, in is_authorized_dag
       return self._is_authorized(
     File 
".../airflow/providers/keycloak/auth_manager/keycloak_auth_manager.py", line 
320, in _is_authorized
       raise AirflowException(f"Unexpected error: {resp.status_code} - 
{resp.text}")
   ```
   
   A similar stack trace appears for `is_authorized_asset` when the UI calls 
`/api/v2/assets/events`.
   
   Keycloak returns `401 invalid_grant / Invalid bearer token` to the UMA 
authorization request once the access token has expired. Instead of treating 
this as “user needs to re-authenticate” and returning a 401/403 back to the 
browser, `KeycloakAuthManager._is_authorized()` raises `AirflowException`, 
which is then surfaced as a **500** from the API.
   
   If I log out and log in again, the UI works for the next access-token TTL 
window and then fails in the same way.
   
   ### Expected behavior
   
   When the access token used by `KeycloakAuthManager` is expired and Keycloak 
answers with `401 invalid_grant`, I would expect one of the following:
   
   * Either the auth manager:
   
     * treats this as an **unauthorized** user and lets the FastAPI layer 
return **401/403** so that the UI can redirect back to the login page, or
   * (even better) if a refresh token/session is available:
   
     * refreshes the token and retries the UMA call, or
     * on failure, still returns 401/403 instead of raising `AirflowException`.
   
   Right now, the expired token leads to an unhandled path in 
`_is_authorized()` and surfaces as a 500, which looks like a server error 
instead of an expired session.
   
   I can reliably reproduce this by setting the Keycloak client access token 
lifespan to 2 minutes.
   Happy to provide more detailed logs or test a patch/PR if that would help.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to