8000 🐛 Use `401` status code in security classes when credentials are missing by YuriiMotov · Pull Request #13786 · fastapi/fastapi · GitHub
[go: up one dir, main page]

Skip to content

🐛 Use 401 status code in security classes when credentials are missing #13786

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

YuriiMotov
Copy link
Contributor
@YuriiMotov YuriiMotov commented Jun 11, 2025

Description

This PR is an attempt to finally solve the issue with security tools returning error responses with status code 403 instead of 401 when credentials are not provided.

Breaking changes and workaround

These changes can break projects that rely on old behavior.
In order to mitigate this, the not_authenticated_status_code is introduced. If set to 403, it will make it work the same way as it was before changes (return 403 status code).
This option should be treated as a temporary workaround to give developers more time to update Clients to follow the new behavior.

Changes and reasoning

APIKeyQuery, APIKeyHeader, APIKeyCookie

  • Standard:
    • These schemes are not covered by standards, but developers usually follow the same rules as for other standards
  • Actions:
    • The default status code for not providing API key was changed from 403 to 401.
    • Temporary not_authenticated_status_code parameter can be used to revert this behavior back to returning 403 error code without sending WWW-Authenticate.
  • Notes:
    • It’s considered to be a good practice to include in WWW-Authenticate information needed to understand how the key is supposed to be passed. I implemented default format (WWW-Authenticate: ApiKey in="...", name="..." ), but it’s possible to override the template for WWW-Authenticate by subclassing and defining the format_www_authenticate_header_value method

HTTP Basic

  • Standard:
  • Actions:
    • No needed. This scheme already acts according to the standard in terms of returning 401 status code with WWW-Authenticate header on a lack of credentials
  • Notes:
    • realm is required according to the RFC, but optional in the current implementation. Fixing this would introduce breaking changes. Considering this is not a problem for people who want to follow the standard, I suggest we leave it as it is.

HTTP Digest

  • Standard:
  • Actions:
    • The default status code for not providing the authorization parameter was changed from 403 to 401.
    • WWW-Authenticate is just a stub for now (just WWW-Authenticate: Digest) (see notes)
    • Temporary not_authenticated_status_code parameter can be used to revert this behavior back to returning 403 error code without sending WWW-Authenticate.
  • Notes:
    • Since the current HTTPDigest implementation is just a stub, we can’t follow standards (we don’t generate nonce's, don’t have realm, …). I suggest we just change the error status code and add a stub for WWW-Authenticate (just WWW-Authenticate: Digest). For now HTTPDigest can’t be used as it is, so, this is not a problem.
    • We can later add full implementation of Digest scheme. There have been made several attempts to implement it (Update HTTPDigest to match RFC 7616 #9825, 🔒 Match HTTP Digest specs from RFC 7616 #3071)
    • Should we add a note that HTTPDigest is just a stub?

HTTP Bearer, OAuth2 schemes, OIDC

  • Standard:
  • Actions:
    • For OAuth2PasswordBearer and OAuth2AuthorizationCodeBearer: not needed.
      • They already return a 401 error code. Implementation is probably not 100% correct (see notes), but considering nobody argued, I think we can leave it as it is for now.
    • For HTTPBearer and OpenIdConnect:
      • The default status code for not providing the authorization parameter was changed from 403 to 401. The suggested implementation will be in line with the current implementations of OAuth2PasswordBearer and OAuth2AuthorizationCodeBearer.
      • Temporary not_authenticated_status_code parameter added to HTTPBearer can be used to revert this behavior back to returning 403 error code without sending WWW-Authenticate.
  • Notes:
    • It’s recommended to return 400 error response if the parameter is missed or of an unsupported type, but this is not a strict requirement (word SHOULD is used). I suggest we ignore this and follow the approach that is consistent with other schemes.
    • The format of WWW-Authenticate is not clearly described: It’s said that the value "Bearer" MUST be followed by one or more auth-param values. At the same time, all auth-param attributes are optional. In examples they always add realm. Since we don’t have realm, I suggest we just skip it and send just WWW-Authenticate: Bearer
    • We can later improve the WWW-Authenticate format by adding realm and scope

Links

@YuriiMotov YuriiMotov added the bug Something isn't working label Jun 11, 2025
@tiangolo tiangolo changed the title 🐛 Use 401 status code in security classes when credentials missed 🐛 Use 401 status code in security classes when credentials are missing Jun 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant
0