Affected Artifact:

      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-oauth2-resource-server</artifactId>
      <version>5.4.7</version>

Describe the bug Given that JWT Authentication is configured for a simple Spring Boot Web Application (http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);) and I protect my endpoints (http.authorizeRequests(requests -> requests.mvcMatchers("/api/**").authenticated());)

when I upload a large file to a controller (@RequestPart(name = "file") MultipartFile file) without proving a Bearer Token or with invalid Bearer Token (e.g. using Postman)

then the large file is uploaded and processed by the application before I receive the response "401 unauthenticated" (e.g. after 7 Minutes, depending on the file size).

Cause: DefaultBearerTokenResolver calls resolveFromRequestParameters even though isParameterTokenSupportedForRequest will be false (as allowFormEncodedBodyParameter is false by default). The included request.getParameterValues("access_token") causes the consumption of the whole multipart content.

Another Problem: Access Tokens have short life time (e.g. 5 minutes). We found ourselves in the situation that the processing triggered by the resolver (request.getParameterValues("access_token")) takes that long that the token is always considered expired by the subsequent logic of the BearerTokenAuthenticationFilter / JwtAuthenticationProvider. (Therefore classified as bug)

We might want to consider to change the code to resolve from request parameters (and check for multiple bearer tokens in the request) etc. only if isParameterTokenSupportedForRequest evaluates true to overcome the outlined two problems.

To Reproduce See Description

Expected behavior - The response "401 unauthenticated" should be returned quite fast. Not after minutes. - The upload of a large file (upload taking longer than JWT life time) should succeed as the according security filter is passed before the file content is processed / uploaded / consumed.

Sample

No sample at hand. Please let me know whether it is necessary to provide one.

Comment From: sjohnr

@regmebaby, thanks for the report. Do you have any interest in submitting a PR to fix the issue in DefaultBearerTokenResolver? I think defaulting the parameterToken to null and only resolving it if isParameterTokenSupportedForRequest(request) returns true would work for your case as well as existing cases.

Comment From: pneuschwander

@regmebaby, thanks for the report. Do you have any interest in submitting a PR to fix the issue in DefaultBearerTokenResolver? I think defaulting the parameterToken to null and only resolving it if isParameterTokenSupportedForRequest(request) returns true would work for your case as well as existing cases.

@sjohnr Great idea, I'll give it a try

Comment From: pneuschwander

@sjohnr I just created a pull request (gh-10340) 🙂