jabbera opened a new issue, #75663:
URL: https://github.com/apache/airflow/issues/75663
### Under which category would you file this issue?
Providers
### Apache Airflow version
3.3.2
### What happened and how to reproduce it?
With the FAB auth manager and OAuth login, opening a deep link (e.g.
`/dags/<dag_id>/tasks/<task_id>`) after the UI JWT (`_token` cookie) has
expired — but while the Flask/FAB `session` cookie is still valid — lands the
user on the Airflow home page instead of the requested page. Clicking the same
link a second time works.
Reproduce:
1. Configure `FabAuthManager` with an OAuth provider (seen with Azure/Entra
ID).
2. Log in, then wait until the `_token` JWT expires (`[api_auth]
jwt_expiration_time`) while the FAB session is still alive (`[fab]
session_lifetime_minutes`), or delete just the `_token` cookie.
3. Open a deep link such as `/dags/<dag_id>/tasks/<task_id>`.
Trace:
1. The SPA gets a 401 and the axios interceptor in `main.tsx` redirects to
`/api/v2/auth/login?next=/dags/<dag_id>/tasks/<task_id>`.
2. That 307s to `/auth/login/?next=/dags/...` (next preserved).
3. `AuthOAuthView.login()` sees `g.user.is_authenticated` and does `return
redirect(self.appbuilder.get_url_for_index)` — `next` is discarded.
4. The provider's `airflow.providers.fab.www.views.redirect` wrapper sets a
fresh `_token` on that redirect, so the user arrives at `/` authenticated, and
the second click succeeds.
When the FAB session is *not* valid, `next` is correctly carried through the
OAuth `state` and honored in `oauth_authorized`, so the bug only affects the
"session valid, JWT expired" path. The same `is_authenticated` early-return
exists in the DB/LDAP/remote-user login views.
### What you think should happen instead?
When the user is already authenticated, the login view should redirect to
the (safe) `next` URL and set the `_token` cookie on that response, so the user
lands on the page they requested.
Flask-AppBuilder fixed the `next` part upstream in
dpgaspar/Flask-AppBuilder#2479 (released in 5.3.0), but `providers/fab` still
pins `flask-appbuilder==5.2.2`. Note that bumping alone is likely insufficient:
FAB's own `redirect` does not set Airflow's `_token` cookie, so the provider's
login views also need to use `airflow.providers.fab.www.views.redirect` for the
authenticated early-return (otherwise the SPA would immediately 401 again and
loop back to login).
Workaround we're using in `webserver_config.py`:
```python
from flask import g, request
from flask_appbuilder import expose
from flask_appbuilder.utils.base import get_safe_redirect
from airflow.providers.fab.auth_manager.security_manager.override import
FabAirflowSecurityManagerOverride
from airflow.providers.fab.auth_manager.views.auth_oauth import
CustomAuthOAuthView
from airflow.providers.fab.www.views import redirect # sets the _token JWT
cookie
class NextAwareAuthOAuthView(CustomAuthOAuthView):
@expose("/login/")
@expose("/login/<provider>")
def login(self, provider=None):
if g.user is not None and g.user.is_authenticated:
return redirect(get_safe_redirect(request.args.get("next",
self.appbuilder.get_url_for_index)))
return super().login(provider)
class SecurityManager(FabAirflowSecurityManagerOverride):
authoauthview = NextAwareAuthOAuthView
SECURITY_MANAGER_CLASS = SecurityManager
```
### Operating System
Linux
### Deployment
Other 3rd-party Helm chart / Kubernetes
### Apache Airflow Provider(s)
fab
### Versions of Apache Airflow Providers
apache-airflow-providers-fab 3.10.2 (flask-appbuilder 5.2.2)
### Anything else?
Happens every time the UI JWT expires while the FAB session is still alive,
so any deep link shared via chat/email/external tools first lands on the home
page.
--
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]