Ignore Content-Type parameters when resolving bearer tokens - #19499
Open
lArtiquel wants to merge 1 commit into
Open
Ignore Content-Type parameters when resolving bearer tokens#19499lArtiquel wants to merge 1 commit into
lArtiquel wants to merge 1 commit into
Conversation
DefaultBearerTokenResolver and ServerBearerTokenAuthenticationConverter
compared the request Content-Type against
application/x-www-form-urlencoded for exact equality. A request that
carries a media type parameter, such as
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
therefore did not qualify as form-encoded, and the access_token body
parameter was silently ignored even with
setAllowFormEncodedBodyParameter(true). The servlet resolver was
additionally case-sensitive, so an upper-case media type was rejected
as well.
Both now parse the Content-Type and compare only its type and subtype,
which is case-insensitive and ignores parameters. Wildcard and
malformed media types continue to be rejected.
Signed-off-by: Artem Tsvirko <tsvirkoartem@gmail.com>
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
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.
Both bearer token resolvers decide whether a request is form-encoded by comparing the
Content-Typefor exact equality:A media type parameter defeats both comparisons.
MediaType#equalsincludes parameters, soapplication/x-www-form-urlencoded;charset=UTF-8is not equal toAPPLICATION_FORM_URLENCODED. That header is legal (RFC 9110 §8.3) and is what several HTTP clients send by default for form bodies. The servlet resolver is additionally case-sensitive, though media types are not (RFC 9110 §8.3.1).The result is a silent failure: with
setAllowFormEncodedBodyParameter(true), theaccess_tokenbody parameter is never read, and the request is rejected as unauthenticated with no indication that the token was present.Reproduce (fails on
mainbefore this change):Fix
Both now parse the
Content-Typeand compare withMimeType#equalsTypeAndSubtype, which is case-insensitive and ignores parameters. Media types that are not form-encoded are still rejected, including*/*—equalsTypeAndSubtypeis used rather thanisCompatibleWithprecisely so that wildcards do not match. In the servlet resolver, an unparseableContent-Typeis treated as not form-encoded rather than propagatingInvalidMediaTypeException; the reactive converter's behaviour on a malformed header is unchanged.Tests cover the charset parameter, upper-case media types,
*/*, and a malformedContent-Type. The reactive converter already normalizes case viaHttpHeaders#getContentType, so its upper-case test passes before and after; it is included to pin the behaviour alongside the servlet one.I did not find an existing issue for this. Happy to open one if you'd prefer the tracking record, and equally happy to target a maintenance branch instead — the servlet resolver has behaved this way since 5.1 and the reactive converter's form-body support since 6.5.
Related, not included:
ServerOneTimeTokenAuthenticationConverter#isFormEncodedRequestcompares the rawContent-Typeheader string the same way and has the same blind spot. I left it out to keep this change to one module and one feature, since fixing it there means routing throughHttpHeaders#getContentType, which throws on a malformed header where the current code does not. Glad to follow up separately if you want it.Verification
Both pass.