-
-
Notifications
You must be signed in to change notification settings - Fork 8.5k
Update HTTPDigest to match RFC 7616 #9825
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
ordinary-jamie
wants to merge
4
commits into
fastapi:master
Choose a base branch
from
ordinary-jamie:feat/http-digest
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4cd2a2b to
67dc386
Compare
67dc386 to
4d3cad0
Compare
HTTP digest access authentication requires the use of a nonce value to prevent replay attacks. This commit introduces a simple stateless nonce for that purpose, following the format recommended by RFC7616 (section 3.3) with a ':' delimited string of timestamp in miliseconds, resource, and server secret data. Note, the nonce utility hash-and-truncates the secret and request URL path to limit the size of the nonce to 48 chars. Also note, the request URL path is used to describe the resource as opposed to the recommended ETag for compatibility reasons.
RFC7616 (section 3.3) requires that "If a server receives a request for an access-protected object, and an acceptable Authorization header field is not sent, the server responds with a "401 Unauthorized" status code..."
This commit introduces a utility to calculate the HTTP digest access authentication consistent with the core elements in RFC 7616. This is an initial implementation of the utility, as many considerations will need to be considered for more a robust implementation, in particular quoted-string handling.
4d3cad0 to
54b1abc
Compare
This is an initial implementation of HTTP Digest Access Authentication consistent to [RFC 7616](https://datatracker.ietf.org/doc/html/rfc7616). As the RFC only provides guidance, and does not enforce all elements of the standard, this commit only implements the crucial aspects to ensure the challenge-response negotiation is at least usable. Notably, non-quoted usernames, and proxy-authentication is not yet supported by this change. Furthermore, this commit uses a stateless-Nonce generation as to avoid overcomplicating the design, future changes may wish to address this to allow servers to validate the nonce is indeed one-time usage.
54b1abc to
ba1a737
Compare
|
LGTM!! |
kjmatsuda
reviewed
Oct 7, 2023
| self.auto_error = auto_error | ||
|
|
||
| async def __call__( | ||
| opqaue_data = realm.encode() if realm else os.urandom(32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is "opqaue_data" a typo for "opaque_data" ?
Member
|
Reminder for Sebastián: we discussed this on July 18th on Slack |
Contributor
|
This pull request has a merge conflict that needs to be resolved. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
🎯 Aim
Closes #1476
🤨 Summary of changes
MD5(timestamp_in_ms:resource:secret). Note, the RFC recommends the header fieldETAGinstead ofresource/URI, however since there is no mentions ofETAGin FastAPI, the PR chooses to use the more readily availablerequest.url.path401 UNAUTHORISEDinstead of403 FORBIDDEN, see RFC 7616, sec 3.3 'the server responds with a "401 Unauthorized" status code and a WWW-Authenticate header field with Digest scheme'HTTPDigestclass to correctly follow the challenge-response framework laid out by RFC 7616.📋 Implementation notes
HTTPDigestCredentials: The resolved-dependency will be of typeHTTPDigestCredentials, which will have anauthenticate(username: str, password: str) -> boolmethod. Because the Digest response is a hashed field, the server can only authenticate a user by comparing the hashed credentials. This method makes this easier for developers.Not implemented
auth-int. However, this requires hashing the entity-body of the request for which we do not have readily available. "the hash of the entity body, not the message body -- it is computed before any transfer encoding is applied by the sender and after it has been removed by the recipient. Note that this includes multipart boundaries and embedded header fields in each part of any multipart content-type."ncfield to allow servers to detect request replays by maintaining its own copy of this count. However, because FastAPI is primarily for RESTful APIs, this PR chooses to not implement this as it would require stateful servers.username*digest field. This PR does not support this.✅ Testing: Manually with CURL
We can validate this implementation is consistent with the RFC by using
curl --digest.First we create a simple server:
Then CURL the running server
References