Spring 5.0.3 RequestRejectedException:请求被拒绝,因为 URL 未规范化 [英] Spring 5.0.3 RequestRejectedException: The request was rejected because the URL was not normalized

查看:141
本文介绍了Spring 5.0.3 RequestRejectedException:请求被拒绝,因为 URL 未规范化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不确定这是 Spring 5.0.3 的一个错误还是一个新功能来修复我的问题.

Not sure if this is a bug with Spring 5.0.3 or a new feature to fix things on my end.

升级后,我收到此错误.有趣的是,这个错误只出现在我的本地机器上.使用 HTTPS 协议在测试环境中使用相同的代码可以正常工作.

After the 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.

继续……

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

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.

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

So my question is, should I remove / from JSP path in code because that's what is required going forward. Or Spring has introduced 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)

推荐答案

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

Spring Security Documentation mentions the reason for blocking // in the request.

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

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 -

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

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

Step 1 Create custom firewall that allows slash in URL.

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

第2步然后在websecurity中配置这个bean

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());
....
}

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

Step 2 is an optional step, Spring Boot just needs a bean to be declared of type HttpFirewall and it will auto-configure it in filter chain.

Spring Security 5.4 更新

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

In Spring security 5.4 and above (Spring Boot >= 2.4.0), we can get rid of too many logs complaining about the request rejected by creating the below bean.

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

@Bean
RequestRejectedHandler requestRejectedHandler() {
   return new HttpStatusRequestRejectedHandler();
}

这篇关于Spring 5.0.3 RequestRejectedException:请求被拒绝,因为 URL 未规范化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆