- spring-boot-starter-parent:2.4.0
- I have
@Controller
with path function with parm@RequestHeader Map<String, String> allHeaders
- Post request with some custom http header key sn: Tomažč but I got error
- error:
[org.springframework.security.web.firewall.StrictHttpFirewall$StrictFirewalledRequest.validateAllowedHeaderValue(StrictHttpFirewall.java:739),
org.springframework.security.web.firewall.StrictHttpFirewall$StrictFirewalledRequest.getHeader(StrictHttpFirewall.java:628),
javax.servlet.http.HttpServletRequestWrapper.getHeader(HttpServletRequestWrapper.java:88),
javax.servlet.http.HttpServletRequestWrapper.getHeader(HttpServletRequestWrapper.java:88),
org.springframework.web.context.request.ServletWebRequest.getHeader(ServletWebRequest.java:129),
org.springframework.web.method.annotation.RequestHeaderMapMethodArgumentResolver.resolveArgument(RequestHeaderMapMethodArgumentResolver.java:83),
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121),
org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170),
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137),
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106),
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:893),
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:807),
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87),
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1061),
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:961),
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006),
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898),
javax.servlet.http.HttpServlet.service(HttpServlet.java:626),
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883),
javax.servlet.http.HttpServlet.service(HttpServlet.java:733),
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231),
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166),
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53),
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193),
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166),
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:113),
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193),
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166),
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327),
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115),
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81),
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336),
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119),
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113),
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336),
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126),
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81),
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336),
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105),
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336),
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149),
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336),
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63),
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336),
si.arnes.dmsedu.security.JwtAuthorizationTokenFilter.doFilterInternal(JwtAuthorizationTokenFilter.java:41),
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119),
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336),
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103),
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89),
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336),
org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90),
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75),
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119),
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336),
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110),
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80),
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336),
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55),
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119),
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336),
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211),
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183),
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358),
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271),
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193),
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166),
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100),
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119),
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193),
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166),
org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93),
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119),
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193),
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166),
org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93),
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119),
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193),
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166),
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201),
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119),
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193),
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166),
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202),
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97),
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542),
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143),
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92),
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78),
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343),
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374),
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65),
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868),
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590),
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49),
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149),
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624),
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61),
java.lang.Thread.run(Thread.java:748)]
Comment From: bclozel
HTTP headers usually only allow ASCII characters or strings encoded with MIME header encoding. Is that the case in your sample application?
If the header is properly encoded, could you please provide a sample project reproducing the issue (ideally something simple we can git clone and run to reproduce the problem)?
Thanks!
Comment From: sysmat
- ok but why is char ž ok, is also non-ASCII and there is no error
- with spring-boot-starter-parent:2.3.6.RELEASE works like a charm, no problems with non-ASCII header values
Comment From: wilkinsona
@sysmat A sample project will help us to figure that out.
Comment From: sysmat
It's is from https://start.spring.io/ * maven
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>si.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- main
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
- controller
@RestController
public class RestApi {
@GetMapping("/headers")
public String headers(@RequestHeader Map<String, String> allHeaders) {
allHeaders.forEach((key, value) -> System.out.println("key="+key+", value="+value));
return "oj";
}
}
- ResourcesExceptionHandler:
@ControllerAdvice
@RestController
public class ResourcesExceptionHandler {
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(value = Exception.class)
public void generalException(Exception e) {
System.out.error("Exception="+ e.getMessage()+ "casue="+e.getCause()+"stack="+e.getStackTrace());
}
}
- client
curl http://localhost:8080/headers -H "name: tomažč"
Comment From: snicoll
@sysmat thank you but if you have the project at hand, please share it so that we don't have to copy paste all that text in something that we can run.
Comment From: wilkinsona
This is standard behaviour in Spring Security 5.4 to which Spring Boot 2.4 upgraded. This is mentioned in the Spring Security documentation which also provides some information about configuring the behaviour
Comment From: sysmat
thanks I did't find in change log
Comment From: sysmat
@snicoll English is not my main language, so my expression is limited
* sorry that I can't share the main project and environment, but I can share with you the concept of reading non-ASCII HTTP headers values in this framework is in a big problem.
* is spring semantic versioning compliment
* is spring java ee?
* is spring rfc compliment
* is spring developer-friendly
The main point of issues is not that your users solve your problem but you listen to the problem
Comment From: philwebb
Sorry that I can't share the main project and environment, but I can share with you the concept of reading non-ASCII HTTP headers values in this framework is in a big problem.
Apologies for the confusion, we weren't asking for you to share your main project, we just find it easier when there's a small sample project in a git repo that we can download and run. As you can imagine, we have a lot of issues to deal with so it's always helpful if we can save time when reproducing a bug.
is spring semantic versioning compliment
No it isn't. We don't follow semantic versioning.
is spring java ee?
No
is spring rfc compliment
Depends on the RFC
is spring developer-friendly
I'd like to think so
The main point of issues is not that your users solve your problem but you listen to the problem
Not all users have the same problem. See https://github.com/spring-projects/spring-security/pull/8644 for background about why this change was made.