可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Not sure if this is a bug with Spring 5.0.3 or a new feature to fix things on my end.
After upgrade, I am getting this error. Interestingly this error is only on my local machine. Same code on test environment with HTTPS protocol works fine.
Continuing...
The reason I am getting this error is because my URL for loading the resultant JSP page is /location/thisPage.jsp
. Evaluating code request.getRequestURI()
gives me result /WEB-INF/somelocation//location/thisPage.jsp
. If I fix URL of JSP page to this location/thisPage.jsp
, things work fine.
So my question is, should I remove /
from JSP
path in code because thats what is required going forward. Or Spring
has introduce a bug as the only difference between my machine and test environment is protocol HTTP
versus HTTPS
.
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL was not normalized. at org.springframework.security.web.firewall.StrictHttpFirewall.getFirewalledRequest(StrictHttpFirewall.java:123) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:194) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
回答1:
Spring Security Documentation mentions the reason for blocking // in the request.
For example, it could contain path-traversal sequences (like /../) or multiple forward slashes (//) which could also cause pattern-matches to fail. Some containers normalize these out before performing the servlet mapping, but others don’t. To protect against issues like these, FilterChainProxy uses an HttpFirewall strategy to check and wrap the request. Un-normalized requests are automatically rejected by default, and path parameters and duplicate slashes are removed for matching purposes.
So there are two possible solutions -
- remove double slash (preferred approach)
- Allow // in Spring Security by customizing the StrictHttpFirewall using the below code.
Step 1 Create custom firewall that allows slash in URL.
@Bean public HttpFirewall allowUrlEncodedSlashHttpFirewall() { StrictHttpFirewall firewall = new StrictHttpFirewall(); firewall.setAllowUrlEncodedSlash(true); return firewall; }
Step 2 And then configure this bean in websecurity
@Override public void configure(WebSecurity web) throws Exception { //@formatter:off super.configure(web); web.httpFirewall(allowUrlEncodedSlashHttpFirewall()); .... }
Step 2 is an optional step, Spring Boot just needs a bean to be declared of type HttpFirewall
回答2:
setAllowUrlEncodedSlash(true) didn't work for me. Still internal method isNormalized return false when having double slash.
I replaced StrictHttpFirewall with DefaultHttpFirewall by having the following code only.
@Bean public HttpFirewall defaultHttpFirewall() { return new DefaultHttpFirewall(); }
Working well for me. Any risk by using DefaultHttpFirewall?
回答3:
I encountered the same problem with:
Spring Boot version = 1.5.10
Spring Security version = 4.2.4
The problem occurred on the endpoints, where the ModelAndView
viewName was defined with a preceding forward slash. Example:
ModelAndView mav = new ModelAndView("/your-view-here");
If I removed the slash it worked fine. Example:
ModelAndView mav = new ModelAndView("your-view-here");
I also did some tests with RedirectView and it seemed to work with a preceding forward slash.