litestar: Bug: Guards should not be executed for `OPTIONS` requests

Description

When guards are applied at Controller level , it is blocking the OPTIONS requests and causing error when accessing users on the guards.


  File "/workspace/app/.venv/lib/python3.11/site-packages/litestar/connection/base.py", line 228, in user
    raise ImproperlyConfiguredException("'user' is not defined in scope, install an AuthMiddleware to set it")
litestar.exceptions.http_exceptions.ImproperlyConfiguredException: 500: 'user' is not defined in scope, install an AuthMiddleware to set it

URL to code causing the issue

https://github.com/litestar-org/litestar-fullstack

MCVE

To be included

Steps to reproduce

curl 'http://0.0.0.0:9000/api/tags' \    
  -X 'OPTIONS' \
  -H 'Accept: */*' \
  -H 'Accept-Language: en-US,en;q=0.9' \
  -H 'Access-Control-Request-Headers: authorization,content-type' \
  -H 'Access-Control-Request-Method: POST' \
  -H 'Connection: keep-alive' \
  -H 'Origin: http://localhost:8000' \
  -H 'Referer: http://localhost:8000/' \
  -H 'Sec-Fetch-Mode: cors' \

Screenshots

"![SCREENSHOT_DESCRIPTION](SCREENSHOT_LINK.png)"

Logs

Traceback (most recent call last):
  File "/workspace/app/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 191, in __call__
    await self.app(scope, receive, send)
  File "/workspace/app/.venv/lib/python3.11/site-packages/litestar/routes/http.py", line 77, in handle
    await route_handler.authorize_connection(connection=request)
  File "/workspace/app/.venv/lib/python3.11/site-packages/litestar/handlers/base.py", line 481, in authorize_connection
    await guard(connection, copy(self))  # type: ignore
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/app/.venv/lib/python3.11/site-packages/litestar/utils/sync.py", line 65, in __call__
    return await self.ref.value(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/app/.venv/lib/python3.11/site-packages/litestar/utils/sync.py", line 101, in wrapper
    return await run_sync(applied_kwarg, *args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/app/.venv/lib/python3.11/site-packages/anyio/to_thread.py", line 33, in run_sync
    return await get_async_backend().run_sync_in_worker_thread(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/app/.venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 2106, in run_sync_in_worker_thread
    return await future
           ^^^^^^^^^^^^
  File "/workspace/app/.venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 833, in run
    result = context.run(func, *args)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/app/src/app/domain/accounts/guards.py", line 27, in requires_active_user
    if connection.user.is_active:
       ^^^^^^^^^^^^^^^
  File "/workspace/app/.venv/lib/python3.11/site-packages/litestar/connection/base.py", line 228, in user
    raise ImproperlyConfiguredException("'user' is not defined in scope, install an AuthMiddleware to set it")
litestar.exceptions.http_exceptions.ImproperlyConfiguredException: 500: 'user' is not defined in scope, install an AuthMiddleware to set it

Litestar Version

2.0.1

Platform

  • Linux
  • Mac
  • Windows
  • Other (Please specify in the description above)

About this issue

  • Original URL
  • State: closed
  • Created 9 months ago
  • Reactions: 1
  • Comments: 18 (13 by maintainers)

Most upvoted comments

Sorry for late reply , after raising this issue i got sick due to food poison . @guacs already fixed it and i am marking it as closed.

I am thinking if it is fit better with your title because it happens on Controller and APP level. What if we apply directly to options decorator ? ( should not do that but for whatever reason , if someone want to do?) should this still execute?

The fix that was made in #2325 does NOT fix this issue by preventing guards from called for OPTIONS requests. It only prevents the middleware from being executed for OPTIONS requests by default.

There was already a mechanism for avoiding calling the middleware based on the HTTP method, but there is not an in-built mechanism for guards as of now.