trina242 commented on issue #57981: URL: https://github.com/apache/airflow/issues/57981#issuecomment-3802968624
> More importantly, why are we redirected to the airflow app, while the authentication appears to not be completed? Normally the auth flow should complete before redirecting back to the airflow UI. @pierrejeambrun I think the point here is that we're not redirected **back** to the app, it's the app trying to render stuff **before** it redirects to login. It's difficult to reproduce locally because everything happens immediately. But even with SimpleAuthManager the first logs from web are always something like this: ``` GET / HTTP/1.1" 200 OK GET /ui/config HTTP/1.1" 401 Unauthorized GET /api/v2/auth/login?next=http%3A%2F%2Flocalhost%3A8080%2F HTTP/1.1" 307 Temporary Redirect ``` which brings us [here](https://github.com/apache/airflow/blob/73451c57ec86049000cf2bbb19c59f59f6bb5f8c/airflow-core/src/airflow/ui/src/main.tsx#L49). We open app, app sends first request, API returns 401, response is intercepted, app redirects to login. I guess the problem here is the logic of redirection to login is placed in the interceptor while it should be handled via router (or somewhere - I'm not much of a frontend person). A simplest way to reproduce is adding `sleep` before returning response in auth manager: ```python from time import sleep from urllib.parse import urljoin from airflow.configuration import conf from airflow.api_fastapi.auth.managers.base_auth_manager import BaseAuthManager from airflow.api_fastapi.auth.managers.models.base_user import BaseUser from airflow.api_fastapi.app import ( AUTH_MANAGER_FASTAPI_APP_PREFIX, ) from airflow.api_fastapi.common.router import AirflowRouter from fastapi import FastAPI from fastapi.responses import PlainTextResponse BASE_URL = conf.get("api", "base_url", fallback="/") class FakeUser(BaseUser): def get_id(self): return "1" def get_name(self): return "Dummy" class FakeAuthManager(BaseAuthManager[FakeUser]): def get_fastapi_app(self): router = AirflowRouter() @router.get("/login") async def dummy(): sleep(10) return PlainTextResponse("Fake login page") app = FastAPI() app.include_router(router) return app def get_url_login(self, **kwargs): return urljoin(BASE_URL, f"{AUTH_MANAGER_FASTAPI_APP_PREFIX}/login") def deserialize_user(self, token): return FakeUser() def serialize_user(self, user): return { "sub": user.get_id(), "username": user.get_name(), } def is_authorized_configuration( self, *args ) -> bool: return True def is_authorized_connection( self, *args ) -> bool: return True def is_authorized_dag( self, *args ) -> bool: return True def is_authorized_backfill( self, *args ) -> bool: return True def is_authorized_asset( self, *args ) -> bool: return True def is_authorized_asset_alias( self, *args ) -> bool: return True def is_authorized_pool( self, *args ) -> bool: return True def is_authorized_variable( self, *args ) -> bool: return True def is_authorized_view( self, *args ) -> bool: return True def is_authorized_custom_view( self, *args) -> bool: return True def filter_authorized_menu_items( self, menu_items, *args ): return [menu_item for menu_item in menu_items] ``` I hope that helps 😉 -- 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]
