Spring 5.0.3 RequestRejectedException:请求被拒绝,因为URL未规范化

jav*_*ude 73 spring-mvc spring-security

不确定这是否是Spring 5.0.3的一个错误或一个新功能来解决我的问题.

升级后,我收到此错误.有趣的是,此错误仅在我的本地计算机上.使用HTTPS协议的测试环境上的相同代码工作正常.

继续...

我收到此错误的原因是因为我加载生成的JSP页面的URL是/location/thisPage.jsp.评估代码request.getRequestURI()给了我结果/WEB-INF/somelocation//location/thisPage.jsp.如果我将JSP页面的URL修复为此location/thisPage.jsp,则工作正常.

所以我的问题是,我应该/JSP代码中的路径中删除,因为这是未来需要的.或者Spring引入了一个错误,因为我的机器和测试环境之间的唯一区别是协议HTTPHTTPS.

org.springframework.security.web.firewall.RequestRejectedException:请求被拒绝,因为URL未规范化.org.springframework.security.web.firewall.StrictHttpFirewall.getFirewalledRequest(StrictHttpFirewall.java:123)org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:194)org.springframework.security.web.FilterChainProxy .doFilter(FilterChainProxy.java:186)org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)

Mun*_*del 55

Spring Security Documentation提到在请求中阻止//的原因.

例如,它可能包含路径遍历序列(如/../)或多个正斜杠(//),这也可能导致模式匹配失败.一些容器在执行servlet映射之前将这些规范化,但其他容器则没有.为了防止这些问题,FilterChainProxy使用HttpFirewall策略来检查和包装请求.默认情况下会自动拒绝未规范化的请求,并且会删除路径参数和重复斜杠以进行匹配.

所以有两种可能的解决方案 -

  1. 删除双斜线(首选方法)
  2. 通过使用以下代码自定义StrictHttpFirewall,在Spring Security中允许//.

步骤1 创建允许在URL中使用斜杠的自定义防火墙.

@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
    StrictHttpFirewall firewall = new StrictHttpFirewall();
    firewall.setAllowUrlEncodedSlash(true);    
    return firewall;
}
Run Code Online (Sandbox Code Playgroud)

步骤2然后在websecurity中配置此bean

@Override
public void configure(WebSecurity web) throws Exception {
    //@formatter:off
    super.configure(web);
    web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
....
}
Run Code Online (Sandbox Code Playgroud)

第2步是可选步骤,Spring Boot只需要声明类型的bean HttpFirewall

  • 这实际上并没有解决方案,至少对于Spring Security 5.1.1.如果您需要带有两个斜杠的网址,例如a/b // c,则必须使用DefaultHttpFirewall.在StrictHttpFirewall中无法配置或覆盖isNormalized方法. (4认同)

小智 20

setAllowUrlEncodedSlash(true)对我不起作用.仍然内部方法isNormalized具有双斜线时返回false.

我通过仅使用以下代码将DefaultTttHirepFirewall替换为DefaultHttpFirewall.

@Bean
public HttpFirewall defaultHttpFirewall() {
    return new DefaultHttpFirewall();
}
Run Code Online (Sandbox Code Playgroud)

对我有用.使用DefaultHttpFirewall有任何风险吗?

  • @java_dude很好,你没有提供任何信息或理由,只是一个模糊的比喻. (9认同)

Tor*_*erv 8

我遇到了同样的问题:

Spring Boot版本= 1.5.10
Spring Security版本= 4.2.4


问题发生在端点上,其中ModelAndViewviewName是使用前面的正斜杠定义的.例:

ModelAndView mav = new ModelAndView("/your-view-here");
Run Code Online (Sandbox Code Playgroud)

如果我删除斜线它工作正常.例:

ModelAndView mav = new ModelAndView("your-view-here");
Run Code Online (Sandbox Code Playgroud)

我还使用RedirectView进行了一些测试,它似乎与前面的正斜杠一起工作.

  • 那不是解决方案。如果这是Spring方面的错误,该怎么办。如果他们更改了它,那么您将不得不再次撤消所有更改。我宁愿等到5.1标记为可解决。 (2认同)

Vik*_*mar 6

一旦我在调用API时使用了双斜杠,那么我将得到相同的错误。

我不得不打电话给http:// localhost:8080 / getSomething,但我确实喜欢http:// localhost:8080 // getSomething。我通过删除多余的斜杠解决了它。


Bin*_*xin 5

就我而言,从 spring-securiy-web 3.1.3 升级到 4.2.12,默认情况下defaultHttpFirewall从 更改DefaultHttpFirewallStrictHttpFirewall。所以只需在 XML 配置中定义它,如下所示:

<bean id="defaultHttpFirewall" class="org.springframework.security.web.firewall.DefaultHttpFirewall"/>
<sec:http-firewall ref="defaultHttpFirewall"/>
Run Code Online (Sandbox Code Playgroud)

设置HTTPFirewallDefaultHttpFirewall