Spring 5.0.3 RequestRejectedException:请求被拒绝,因为 URL 未标准化

2023-12-06

不确定这是否是 Spring 5.0.3 的一个错误,或者是一个新功能来修复我的问题。

升级后,我收到此错误。有趣的是,这个错误仅出现在我的本地计算机上。使用 HTTPS 协议的测试环境中的相同代码运行良好。

继续...

我收到此错误的原因是因为我用于加载结果 JSP 页面的 URL 是/location/thisPage.jsp。评估代码request.getRequestURI()给我结果/WEB-INF/somelocation//location/thisPage.jsp。如果我将 JSP 页面的 URL 固定为此location/thisPage.jsp,一切正常。

所以我的问题是,我应该删除/ from JSP代码中的路径,因为这是未来所需要的。或者Spring引入了一个错误,因为我的机器和测试环境之间的唯一区别是协议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)

Spring安全文档在请求中提到了阻止 // 的原因。

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

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

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

Step 1创建允许 URL 中出现斜杠的自定义防火墙。

@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
    StrictHttpFirewall firewall = new StrictHttpFirewall();
    firewall.setAllowUrlEncodedSlash(true);    
    return firewall;
}

Step 2然后在websecurity中配置这个bean

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

步骤2是可选步骤,Spring Boot只需要声明一个类型的beanHttpFirewall它会在过滤器链中自动配置它。

Spring安全5.4更新

在 Spring security 5.4 及更高版本(Spring Boot >= 2.4.0)中,我们可以通过创建以下 bean 来消除太多抱怨请求被拒绝的日志。

import org.springframework.security.web.firewall.RequestRejectedHandler;
import org.springframework.security.web.firewall.HttpStatusRequestRejectedHandler;

@Bean
RequestRejectedHandler requestRejectedHandler() {
   return new HttpStatusRequestRejectedHandler();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring 5.0.3 RequestRejectedException:请求被拒绝,因为 URL 未标准化 的相关文章

随机推荐