dudil / fastapi_msal

A FastAPI Plug-In to support authentication authorization using the Microsoft Authentication Library (MSAL)
MIT License
38 stars 20 forks source link

Expired token return Internal Server Error #15

Closed u-iandono closed 9 months ago

u-iandono commented 2 years ago

Describe the bug When you put an already expired token, it will return an internal server error.

To Reproduce Steps to reproduce the behavior:

  1. Go to FastAPI autogenerated documentation /docs
  2. Wait until the token expired
  3. Try out a request

Expected behavior It should return 401 Unauthorized instead of internal server error

Environment Settings

Additional context Error trace:

Traceback (most recent call last):
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\uvicorn\protocols\http\httptools_impl.py", line 376, in run_asgi  
    result = await app(self.scope, self.receive, self.send)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 75, in __call__        
    return await self.app(scope, receive, send)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\fastapi\applications.py", line 212, in __call__
    await super().__call__(scope, receive, send)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\starlette\applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
    raise exc
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\starlette\middleware\cors.py", line 84, in __call__
    await self.app(scope, receive, send)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\starlette\middleware\sessions.py", line 77, in __call__
    await self.app(scope, receive, send_wrapper)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\starlette\exceptions.py", line 82, in __call__
    raise exc
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\starlette\exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\starlette\routing.py", line 656, in __call__
    await route.handle(scope, receive, send)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\starlette\routing.py", line 259, in handle
    await self.app(scope, receive, send)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\starlette\routing.py", line 61, in app
    response = await func(request)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\fastapi\routing.py", line 216, in app
    solved_result = await solve_dependencies(
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\fastapi\dependencies\utils.py", line 498, in solve_dependencies   
    solved_result = await solve_dependencies(
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\fastapi\dependencies\utils.py", line 527, in solve_dependencies   
    solved = await call(**sub_values)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\fastapi_msal\security\msal_scheme.py", line 47, in __call__       
    token_claims: Optional[IDTokenClaims] = await self.handler.parse_id_token(
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\fastapi_msal\security\msal_auth_code_handler.py", line 79, in pars
e_id_token
    return await self.msal_app().validate_id_token(id_token=id_token)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\fastapi_msal\clients\async_conf_client.py", line 50, in validate_i
d_token
    token_claims: OptStrsDict = await self.__execute_async__(
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\fastapi_msal\clients\async_conf_client.py", line 37, in __execute_
async__
    result: T = await run_in_threadpool(func, **kwargs)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\starlette\concurrency.py", line 39, in run_in_threadpool
    return await anyio.to_thread.run_sync(func, *args)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\anyio\to_thread.py", line 28, in run_sync
    return await get_asynclib().run_sync_in_worker_thread(func, *args, cancellable=cancellable,
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\anyio\_backends\_asyncio.py", line 818, in run_sync_in_worker_thre
ad
    return await future
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\anyio\_backends\_asyncio.py", line 754, in run
    result = context.run(func, *args)
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\msal\oauth2cli\oidc.py", line 107, in decode_id_token
    return decode_id_token(
  File "C:\Users\x\.virtualenvs\y-M0aUaMTg\lib\site-packages\msal\oauth2cli\oidc.py", line 76, in decode_id_token
    raise RuntimeError("%s Current epoch = %s.  The id_token was: %s" % (
RuntimeError: 9. The current time MUST be before the time represented by the exp Claim. Current epoch = 1644427758.  The id_token was: {
  "aud": "7907897b-f451-4056-a529-xxxxxxxxxxxx",
  "iss": "https://login.microsoftonline.com/94118b0c-61a0-42a1-99c9-xxxxxxxxxxxx/v2.0",
  "iat": 1644417071,
  "nbf": 1644417071,
  "exp": 1644420971,
  "idp": "https://sts.windows.net/9188040d-6c67-4c5b-b112-xxxxxxxxxxxx/",
  "name": "111 dbss",
  "nonce": "edfe0744ff8456867b3c7a0bf3c252a7e053b33e97cbf5dd9012fe9b3944376f",
  "oid": "c47f7dbb-ecd3-475c-ab5b-xxxxxxxxxxxx",
  "preferred_username": "email@gmail.com",
  "rh": "0.AXEADIsRlKBhoUKZyeU0YCG2pnuJB3lR9FZApSly7PrGSQ-HALI.",
  "sub": "j-eDpYyo8Dbr8cNwdiQwXzl_xxxxxxxxxxxxxxxxx",
  "tid": "94118b0c-61a0-42a1-99c9-xxxxxxxxxxxx",
  "uti": "vXXE-Eq6PE-xxxxxxxxxxx",
  "ver": "2.0"
}
dudil commented 9 months ago

Thank you @u-iandono, this issue is now fixed and will be pushed on the next release 🙏