Springboot version 2.3.4.RELEASE

Jetty version jetty-9.4.31.v20200723; built: 2020-07-23T17:57:36.812Z; git: 450ba27947e13e66baa8cd1ce7e85a4461cacc1d; jvm 15+36-1562 Java version OpenJDK Runtime Environment (build 15+36-1562) OS type/version Windows 10 Description

Hi,

first of all I'm not sure if this is Jetty issue or spring.

I have bearer protected app. I have set Multipart max file size and max request size to 10mb. MultipartConfigFactory factory = new MultipartConfigFactory(); factory.setMaxFileSize(DataSize.ofMegabytes(10)); factory.setMaxRequestSize(DataSize.ofMegabytes(10)); return factory.createMultipartConfig();

Authorization header is correctly set as everything works for files under the limit.

But when I try to upload a file bigger than that jetty (correctly) throws exception if (MultiPartInputStreamParser.this._config.getMaxFileSize() > 0 && _size + 1 > MultiPartInputStreamParser.this._config.getMaxFileSize()) throw new IllegalStateException("Multipart Mime part " + _name + " exceeds max filesize"); This later gets mapped to BadMessageException org.eclipse.jetty.server.HttpChannel [qtp765329253-31] handleException /my-path org.eclipse.jetty.http.BadMessageException: 400: Unable to parse form content

I would expect 400 code here as I need to notify client that he tried to upload too big file.

But the app returns 401 Unauthorized. This jetty exception happens when BearerTokenAuthenticationFilter calls DefaultBearerTokenResolver.resolve.

BearerTokenAuthenticationEntryPoint receives authException InsufficientAuthenticationException "Full authentication is required to access this resource" hence 401.

401 is wrong, seems like jetty exception leads to failure to obtain Authorization header.

My guess this is bug on spring. Any workaround this so I would return 400 in case of BadMessageException?

Comment From: eleftherias

Thanks for reaching out @MatCuk. Can you provide a minimal sample that reproduces this issue?

Comment From: MatCuk

Checkout: https://github.com/MatCuk/spring-issue-9181

In postman select POST to localhost:8080/upload Spring Security Spring in combination with jetty BadMessageException returns 401 instead of 400

If you select file bigger than 10mb you get 401.

Comment From: eleftherias

Thanks for the sample @MatCuk.

Looking at the logs I see that Jetty is performing an error dispatch when the file size exceeds the max.

Logs:

2020-11-16 17:27:38.450 DEBUG 48926 --- [tp1934729582-45] org.eclipse.jetty.server.session         : Entering scope org.eclipse.jetty.server.session.SessionHandler475024998==dftMaxIdleSec=1800, dispatch=ERROR asyncstarted=false
2020-11-16 17:27:38.450 DEBUG 48926 --- [tp1934729582-45] org.eclipse.jetty.server.session         : sessionHandler=org.eclipse.jetty.server.session.SessionHandler475024998==dftMaxIdleSec=1800 session=null
2020-11-16 17:27:38.450 DEBUG 48926 --- [tp1934729582-45] o.eclipse.jetty.servlet.ServletHandler   : servlet |/error|null -> dispatcherServlet@7ef5559e==org.springframework.web.servlet.DispatcherServlet,jsp=null,order=-1,inst=true,async=true

This causes it to try to access the "/error" page which is secured and therefore you see a 401 response.

One solution is to permit access to the "/error" page, assuming that there is no sensitive information on there.

        http.authorizeRequests(authorize -> authorize
            .antMatchers("/error").permitAll()
            .anyRequest().authenticated()
        )
        // ...

Based on this issue, I have also created gh-9205, which will allow you to define what security rules apply on an error dispatch.

Comment From: MatCuk

Ok, will try. Thanks!

Comment From: MatCuk

Can confirm it works now.