dabla opened a new issue, #76352:
URL: https://github.com/apache/airflow/issues/76352

   ### Under which category would you file this issue?
   
   Providers
   
   ### Apache Airflow version
   
   3.3.2 (also reproduced against main; the code path is unchanged in 3.4.0rc 
with `apache-airflow-providers-keycloak` 0.11.2)
   
   ### What happened and how to reproduce it?
   
   With the Keycloak auth manager, a browser session whose Keycloak tokens can 
no longer be used makes every authorized API call fail with a 500 instead of 
sending the user back to the login page. We hit it in the morning, after the 
Keycloak refresh token had expired overnight.
   
   ```
   File ".../airflow/providers/keycloak/auth_manager/keycloak_auth_manager.py", 
line 310, in is_authorized_dag
       return self._is_authorized(
   File ".../airflow/providers/keycloak/auth_manager/keycloak_auth_manager.py", 
line 513, in _is_authorized
       headers=self._get_headers(user.access_token),
   AttributeError: 'NoneType' object has no attribute 'access_token'
   ```
   
   `GET /api/v2/dags/~/dagRuns` and `GET /ui/dags` returned 500 for every poll 
of the UI.
   
   What happens, step by step (provider 0.10.0 on Airflow 3.3.2, same code on 
main):
   
   1. The browser still sends the Airflow JWT cookie, but 
`KeycloakJWTMiddleware._refresh_user` raises: the Keycloak refresh token 
expired (`AuthManagerRefreshTokenExpiredException`), or the Keycloak access 
token cookie is missing (`HTTPException` 401).
   2. `dispatch` catches it, leaves `request.state.user` unset and still calls 
the route.
   3. `security.get_user` falls back to `resolve_user_from_token(<Airflow JWT 
cookie>)`, which calls `KeycloakAuthManager.get_user_from_token(token)` without 
Keycloak tokens.
   4. Since Airflow 3.3 the browser JWT no longer carries the Keycloak tokens, 
so `get_user_from_token` ends with `return user if user.access_token else None`.
   5. `None` is passed as `user` to `is_authorized_dag`, and `_is_authorized` 
dereferences `user.access_token`.
   
   Because the request ends in an exception, the middleware never gets to clear 
the session cookie either, so the user stays stuck on 500s until they delete 
the cookies by hand.
   
   To reproduce: log in to the UI with the Keycloak auth manager, then delete 
the Keycloak access token cookie (or wait until the Keycloak refresh token has 
expired) and reload the Dags page.
   
   ### What you think should happen instead?
   
   `get_user_from_token` should keep the contract of 
`BaseAuthManager.get_user_from_token` and raise `InvalidTokenError` when it 
cannot build a user. `resolve_user_from_token` then answers 403 "Invalid JWT 
token", which the UI already treats as "go to the login page", and the 
middleware clears the session cookie on the way out.
   
   ### Operating System
   
   Linux (containers on Kubernetes)
   
   ### Deployment
   
   Other 3rd-party Helm chart
   
   ### Apache Airflow Provider(s)
   
   keycloak
   
   ### Versions of Apache Airflow Providers
   
   apache-airflow-providers-keycloak==0.10.0 (code unchanged up to 0.11.2 and 
main)
   
   ### Anything else?
   
   #70707 reworks the middleware for Airflow 3.4.1+, but it does not change 
this path for 3.3 and 3.4.0.
   
   ### Are you willing to submit PR?
   
   - [X] Yes I am willing to submit a PR!
   
   ### Code of Conduct
   
   - [X] I agree to follow this project's Code of Conduct
   


-- 
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