equinor / webviz

Mozilla Public License 2.0
6 stars 8 forks source link

`AttributeError` in `auth_helper` #105

Open anders-kiaer opened 1 year ago

anders-kiaer commented 1 year ago
backend_1   | Traceback (most recent call last):
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/uvicorn/protocols/http/h11_impl.py", line 407, in run_asgi
backend_1   |     result = await app(  # type: ignore[func-returns-value]
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
backend_1   |     return await self.app(scope, receive, send)
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/fastapi/applications.py", line 270, in __call__
backend_1   |     await super().__call__(scope, receive, send)
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/starlette/applications.py", line 124, in __call__
backend_1   |     await self.middleware_stack(scope, receive, send)
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 184, in __call__
backend_1   |     raise exc
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 162, in __call__
backend_1   |     await self.app(scope, receive, _send)
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/starsessions/middleware.py", line 138, in __call__
backend_1   |     await self.app(scope, receive, send_wrapper)
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/starlette/middleware/base.py", line 106, in __call__
backend_1   |     response = await self.dispatch_func(request, call_next)
backend_1   |   File "/home/appuser/backend/./src/fastapi_app/auth/enforce_logged_in_middleware.py", line 70, in dispatch
backend_1   |     response = await call_next(request)
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/starlette/middleware/base.py", line 80, in call_next
backend_1   |     raise app_exc
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/starlette/middleware/base.py", line 69, in coro
backend_1   |     await self.app(scope, receive_or_disconnect, send_no_error)
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
backend_1   |     return await self.app(scope, receive, send)
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
backend_1   |     raise exc
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
backend_1   |     await self.app(scope, receive, sender)
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
backend_1   |     raise e
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
backend_1   |     await self.app(scope, receive, send)
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/starlette/routing.py", line 706, in __call__
backend_1   |     await route.handle(scope, receive, send)
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/starlette/routing.py", line 276, in handle
backend_1   |     await self.app(scope, receive, send)
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/starlette/routing.py", line 66, in app
backend_1   |     response = await func(request)
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/fastapi/routing.py", line 237, in app
backend_1   |     raw_response = await run_endpoint_function(
backend_1   |   File "/home/appuser/.local/lib/python3.8/site-packages/fastapi/routing.py", line 163, in run_endpoint_function
backend_1   |     return await dependant.call(**values)
backend_1   |   File "/home/appuser/backend/./src/fastapi_app/routers/general.py", line 39, in logged_in_user
backend_1   |     authenticated_user = AuthHelper.get_authenticated_user(request)
backend_1   |   File "/home/appuser/backend/./src/fastapi_app/auth/auth_helper.py", line 140, in get_authenticated_user
backend_1   |     expiration_time = id_token_claims.get("exp", 0)
backend_1   | AttributeError: 'NoneType' object has no attribute 'get'
anders-kiaer commented 1 year ago

Problem still seems to persist. A workaround might be to change line 138 here https://github.com/equinor/webviz/blob/48f51276898d8edb09363ffa20a58ddd2d1dd44a/backend/src/fastapi_app/auth/auth_helper.py#L138 to:

        id_token_claims = request_with_session.session.get("logged_in_user_id_token_claims") or {}

For some reason the .get() function on line 138 returns None, so the default value {} is not used.

anders-kiaer commented 1 year ago

The error seems a bit flaky (but is consistent when it first starts appearing). It was working for some hours on my laptop, and now suddenly this error started appearing again without changes to backend dependencies / auth-helper.

Deleting cookie on localhost:8080 resolved it for me.

sigurdp commented 1 year ago

Further investigation strongly indicates that the cause of this error is changes introduced in MSAL 1.21 Apparently we're no longer able to get id_token_claims from acquire_token_silent() by passing our client id as scope. Have done som initial investigations and experiments to try and resolve this without success, so for now let's simply lock the MSAL version to 1.20 (see PR #109)

We should refactor our authentication code to not rely on the id_token_claims, but rather get the user information and expiry time in another way. We can probably get the user information (through the id_token or the id_token_claims) during the initial processing of the auth callback. The expiry time we should be able to deduce from the access tokens and just keep track of it ourselves.