Spring Boot 不允许 URL 中的百分比和反斜杠
Springboot doesn't let through percentage and backslash in URL
我们收到一个发送字符串字符的get请求url,所以我们使用路径变量来接收它们。显然,调用服务无法更改其调用后端的方法,因此我们需要能够接受具有以下未编码字符的 url:
发送百分号 % 时返回 http 400。如果 % 后面的两个字符组成一个 UTF 编码字符
,它确实会通过
反斜杠转换为正斜杠。我需要它来保留反斜杠。
我猜这些可能是 Tomcat 或 servlet 配置问题。
(spring 引导版本 1.5.14.RELEASE)
final String path =
request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString();
final String bestMatchingPattern =
request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString();
String arguments = new AntPathMatcher().extractPathWithinPattern(bestMatchingPattern, path);
if (null != arguments && !arguments.isEmpty()) {
pattern = pattern + '/' + arguments;
}
我也遇到过类似的问题,我用过这个,希望这能对你有所帮助
百分号 (%) 如果您正确 URL 对其进行编码 (%25
),应该没有问题。但是,斜杠和反斜杠不适用于 Tomcat,即使您对它们进行编码(%2F
和 %5C
)也是如此。
您可以在 运行 应用程序时设置以下属性:
-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
-Dorg.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true
但是,这并不能解决问题,因为在这种情况下,那些经过编码的斜杠将被识别为真实斜杠。因此,假设您有以下控制器:
@ResponseBody
@RequestMapping("/api/{foo}")
public String getFoo(@PathVariable String foo) {
return foo;
}
好吧,那么如果你调用/api/test%5Ctest
,它将无法找到正确的路径。此问题的解决方案是使用通配符匹配器并从传入的 HttpServletRequest
:
中解析 URL 本身
@RequestMapping("/api/**")
public String getFoo(HttpServletRequest request) {
// ...
}
另一种解决方案是使用完全不同的网络容器。例如,使用 Jetty 时,这根本不是问题,URL 编码的斜杠和反斜杠都可以。
您遇到的问题并非 Spring Boot 所特有。相反,它是 HTTP 的限制。
HTTP 标准要求任何包含百分比字符的 URL 必须由 Web 服务器解码(参见第 36 页):
If the Request-URI is encoded using the "% HEX HEX" encoding [42], the
origin server MUST decode the Request-URI in order to properly
interpret the request.
因此,无法可靠地转义斜线字符。
因此,当在 URL 中使用斜杠时——无论是否进行编码——它都将被视为路径分隔符。所以它不能用在 Spring 引导路径变量中。百分号和反斜杠存在类似问题。
您最好的选择是使用查询参数或 POST 请求。
在下面的URL中,传值test_with_/and_%
:
https://host/abc/def?text=test_with_%2F_and%25
Spring 5 现在默认阻止编码百分号。要启用它们,请创建一个调用 setAllowUrlEncodedPercent()
的新 Bean
@Bean
public HttpFirewall allowEncodedParamsFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedPercent(true);
return firewall;
}
有类似的方法调用
我们收到一个发送字符串字符的get请求url,所以我们使用路径变量来接收它们。显然,调用服务无法更改其调用后端的方法,因此我们需要能够接受具有以下未编码字符的 url:
发送百分号 % 时返回 http 400。如果 % 后面的两个字符组成一个 UTF 编码字符
,它确实会通过反斜杠转换为正斜杠。我需要它来保留反斜杠。
我猜这些可能是 Tomcat 或 servlet 配置问题。
(spring 引导版本 1.5.14.RELEASE)
final String path =
request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString();
final String bestMatchingPattern =
request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString();
String arguments = new AntPathMatcher().extractPathWithinPattern(bestMatchingPattern, path);
if (null != arguments && !arguments.isEmpty()) {
pattern = pattern + '/' + arguments;
}
我也遇到过类似的问题,我用过这个,希望这能对你有所帮助
百分号 (%) 如果您正确 URL 对其进行编码 (%25
),应该没有问题。但是,斜杠和反斜杠不适用于 Tomcat,即使您对它们进行编码(%2F
和 %5C
)也是如此。
您可以在 运行 应用程序时设置以下属性:
-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
-Dorg.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true
但是,这并不能解决问题,因为在这种情况下,那些经过编码的斜杠将被识别为真实斜杠。因此,假设您有以下控制器:
@ResponseBody
@RequestMapping("/api/{foo}")
public String getFoo(@PathVariable String foo) {
return foo;
}
好吧,那么如果你调用/api/test%5Ctest
,它将无法找到正确的路径。此问题的解决方案是使用通配符匹配器并从传入的 HttpServletRequest
:
@RequestMapping("/api/**")
public String getFoo(HttpServletRequest request) {
// ...
}
另一种解决方案是使用完全不同的网络容器。例如,使用 Jetty 时,这根本不是问题,URL 编码的斜杠和反斜杠都可以。
您遇到的问题并非 Spring Boot 所特有。相反,它是 HTTP 的限制。
HTTP 标准要求任何包含百分比字符的 URL 必须由 Web 服务器解码(参见第 36 页):
If the Request-URI is encoded using the "% HEX HEX" encoding [42], the origin server MUST decode the Request-URI in order to properly interpret the request.
因此,无法可靠地转义斜线字符。
因此,当在 URL 中使用斜杠时——无论是否进行编码——它都将被视为路径分隔符。所以它不能用在 Spring 引导路径变量中。百分号和反斜杠存在类似问题。
您最好的选择是使用查询参数或 POST 请求。
在下面的URL中,传值test_with_/and_%
:
https://host/abc/def?text=test_with_%2F_and%25
Spring 5 现在默认阻止编码百分号。要启用它们,请创建一个调用 setAllowUrlEncodedPercent()
的新 Bean@Bean
public HttpFirewall allowEncodedParamsFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedPercent(true);
return firewall;
}
有类似的方法调用