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]