I have spring boot application with undertow container. There is a rest controller that accepts file that look like following:
@ResponseStatus(HttpStatus.CREATED)
@PostMapping(value = {"/v2/upload-csv"},
produces = {MediaType.APPLICATION_JSON_VALUE},
consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public List<ChordInfo> uploadFile(@RequestPart @NotNull(message = "File is not provided!") MultipartFile file) {
return chordService.handleFile(file);
}
With MaxUploadSizeExceededException
exception handler
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorResponse handleFileSizeException(MaxUploadSizeExceededException exception) {
return ErrorResponse.singleError(new Error(
ErrorCode.UPLOAD_SIZE_EXCEEDED,
exception.getMessage(),
new UploadSizeExceededMeta(exception.getMaxUploadSize())
)
);
}
And Basic authentication configuration:
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and().csrf().disable()
.authorizeRequests()
.antMatchers("/**").permitAll()
.and()
.httpBasic();
}
}
It'd worked well until I replaced basic auth to oauth2 resource server with JWT. Now the configuration looks like this
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.anyRequest().permitAll()
.and()
.oauth2ResourceServer()
.jwt();
}
If I try to upload file exceeding limit, the application returns 500
with default spring's exception:
{
"timestamp": "2021-09-03T16:08:13.341+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "",
"path": "/v2/upload-csv"
}
How could I fix it?
I found out that replacing container to Tomcat
fixes the problem but I'd like to stay on undertow.
UPD1 Here is stack trace with with enabled jwt
ERROR io.undertow.request - UT005023: Exception handling request to /v2/upload-csv
java.lang.IllegalStateException: io.undertow.server.handlers.form.MultiPartParserDefinition$FileTooLargeException: UT000054: The maximum size 1048576 for an individual file in a multipart request was exceeded
at io.undertow.servlet.spec.HttpServletRequestImpl.parseFormData(HttpServletRequestImpl.java:855) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.spec.HttpServletRequestImpl.getParameterValues(HttpServletRequestImpl.java:778) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at javax.servlet.ServletRequestWrapper.getParameterValues(ServletRequestWrapper.java:174) ~[jakarta.servlet-api-4.0.4.jar:4.0.4]
at javax.servlet.ServletRequestWrapper.getParameterValues(ServletRequestWrapper.java:174) ~[jakarta.servlet-api-4.0.4.jar:4.0.4]
at org.springframework.security.web.firewall.StrictHttpFirewall$StrictFirewalledRequest.getParameterValues(StrictHttpFirewall.java:721) ~[spring-security-web-5.4.2.jar:5.4.2]
at javax.servlet.ServletRequestWrapper.getParameterValues(ServletRequestWrapper.java:174) ~[jakarta.servlet-api-4.0.4.jar:4.0.4]
at org.springframework.security.oauth2.server.resource.web.DefaultBearerTokenResolver.resolveFromRequestParameters(DefaultBearerTokenResolver.java:116) ~[spring-security-oauth2-resource-server-5.4.2.jar:5.4.2]
at org.springframework.security.oauth2.server.resource.web.DefaultBearerTokenResolver.resolve(DefaultBearerTokenResolver.java:52) ~[spring-security-oauth2-resource-server-5.4.2.jar:5.4.2]
at org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter.doFilterInternal(BearerTokenAuthenticationFilter.java:106) ~[spring-security-oauth2-resource-server-5.4.2.jar:5.4.2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar:5.3.3]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar:5.3.3]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar:5.3.3]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183) ~[spring-security-web-5.4.2.jar:5.4.2]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) ~[spring-web-5.3.3.jar:5.3.3]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) ~[spring-web-5.3.3.jar:5.3.3]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.3.jar:5.3.3]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar:5.3.3]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.3.jar:5.3.3]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar:5.3.3]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at org.springframework.cloud.sleuth.instrument.web.servlet.TracingFilter.doFilter(TracingFilter.java:89) ~[spring-cloud-sleuth-instrumentation-3.0.1.jar:3.0.1]
at org.springframework.cloud.sleuth.autoconfig.instrument.web.LazyTracingFilter.doFilter(TraceWebServletConfiguration.java:121) ~[spring-cloud-sleuth-autoconfigure-3.0.1.jar:3.0.1]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at org.zalando.logbook.servlet.LogbookFilter.doFilter(LogbookFilter.java:71) ~[logbook-servlet-2.4.2.jar:na]
at org.zalando.logbook.servlet.SecureLogbookFilter.doFilter(SecureLogbookFilter.java:32) ~[logbook-servlet-2.4.2.jar:na]
at org.zalando.logbook.servlet.HttpFilter.doFilter(HttpFilter.java:31) ~[logbook-servlet-2.4.2.jar:na]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93) ~[spring-boot-actuator-2.4.2.jar:2.4.2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar:5.3.3]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.3.jar:5.3.3]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar:5.3.3]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) ~[undertow-core-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) ~[undertow-core-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) ~[undertow-core-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:387) ~[undertow-core-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:841) ~[undertow-core-2.2.3.Final.jar:2.2.3.Final]
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) ~[jboss-threads-3.1.0.Final.jar:3.1.0.Final]
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2019) ~[jboss-threads-3.1.0.Final.jar:3.1.0.Final]
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1558) ~[jboss-threads-3.1.0.Final.jar:3.1.0.Final]
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1449) ~[jboss-threads-3.1.0.Final.jar:3.1.0.Final]
at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]
Caused by: io.undertow.server.handlers.form.MultiPartParserDefinition$FileTooLargeException: UT000054: The maximum size 1048576 for an individual file in a multipart request was exceeded
at io.undertow.server.handlers.form.MultiPartParserDefinition$MultiPartUploadHandler.data(MultiPartParserDefinition.java:272) ~[undertow-core-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.util.MultipartParser$IdentityEncoding.handle(MultipartParser.java:365) ~[undertow-core-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.util.MultipartParser$ParseState.entity(MultipartParser.java:343) ~[undertow-core-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.util.MultipartParser$ParseState.parse(MultipartParser.java:131) ~[undertow-core-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.server.handlers.form.MultiPartParserDefinition$MultiPartUploadHandler.parseBlocking(MultiPartParserDefinition.java:232) ~[undertow-core-2.2.3.Final.jar:2.2.3.Final]
at io.undertow.servlet.spec.HttpServletRequestImpl.parseFormData(HttpServletRequestImpl.java:853) ~[undertow-servlet-2.2.3.Final.jar:2.2.3.Final]
... 86 common frames omitted