解决springbootURL带有斜杠的转义字符百分之2F导致的400错误

解决springbootURL带有斜杠的转义字符百分之2F导致的400错误

2023年6月25日发(作者:)

解决springbootURL带有斜杠的转义字符百分之2F导致的400错误⽬录springboot URL带有斜杠的转义字符百分之2F导致的400错误原因解决⽅式springboot 1.x 2.x tomcat⽀持特殊字符URL中有{}[]等报400解决⽅案sprintboot 1.x(1.5.21测试有效)springboot 2.x(2.1.3测试有效)总结后续springboot URL带有斜杠的转义字符百分之2F导致的400错误今天项⽬上出现⼀个问题,是前端的GET请求url中带有路径参数,这个参数中有/这个特殊字符,前端已经转移成了%2F,后端⽤的是springboot,并没有收到这个请求,直接返回了400的错误原因据说是tomcat默认是不⽀持转义的,需要⼿动设置⼀下转化,这个搜索tomcat的设置可以找到,但是这个是springboot,有内置的tomcat,但是在yml中找不到相关的配置。解决⽅式修改⼀下启动类,加⼀个系统参数,重写WebMvcConfigurerAdapter的configurePathMatch⽅法@SpringBootApplicationpublic class Application extends WebMvcConfigurerAdapter { public static void main(String[] args) throws Exception { perty("_ENCODED_SLASH", "true"); (, args); } @Override public void configurePathMatch(PathMatchConfigurer configurer) { UrlPathHelper urlPathHelper = new UrlPathHelper(); Decode(false); PathHelper(urlPathHelper); }}springboot 1.x 2.x tomcat⽀持特殊字符URL中有{}[]等报400现象正常访问⼀个get请求,页⾯返回400:

后台⽇志报错:2018-08-09 21:39:28.915 INFO 6750 --- [nio-8080-exec-1] 11Processor : Error parsing HTTP request header Note: further occurrences of HTTP header parsing errors will be logged at DEBUG lArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986 at equestLine(:479) ~[:8.5.32] at e(:684) ~[:8.5.32] at s(:66) [:8.5.32] at ctProtocol$s(:800) [:8.5.32] at point$(:1471) [:8.5.32] at (:49) [:8.5.32] at ker(:1142) [na:1.8.0_111] at PoolExecutor$(:617) [na:1.8.0_111] at read$(:61) [:8.5.32] at (:745) [na:1.8.0_111]稍微百度⼀下就可以知道这是URL中有特殊字符,新版本的Tomcat严格按照RFC 3986规范进⾏访问解析,⽽ RFC 3986规范规定Url中只允许包含英⽂字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符(RFC3986/7320中指定了以下字符为保留字符:! * ' ( ) ; : @ & = + $ , / ? # [ ]) 。3.2.6. Field Value Components Most HTTP header field values are defined using common syntax components (token, quoted-string, and comment) separated by whitespace orspecific delimiting characters. Delimiters are chosen from the set of US-ASCII visual characters not allowed in a token (DQUOTE and “(),/:;<=>?@[]{}”).所以这个问题特别容易出现在升级spring boot版本的时候,spring boot内嵌的tomcat也会升级,⽼版的tomcat运⾏正常,新版的tomcat就会出错。⽽深究特殊字符来源,⼀般是get请求中包含json字符串、搜索特殊字符关键字等。解决⽅案如果是在开发新业务过程中出现这个问题,可以选择新的⽅案,避免在GET请求中使⽤! * ' ( ) ; : @ & = + $ , / ? # [ ])等字符,毕竟符合规范是最好的出路。如果是升级,可以使⽤下⾯的⽅式来解决:sprintboot 1.x(1.5.21测试有效)import urableEmbeddedServletContainer;import edServletContainerCustomizer;import ConnectorCustomizer;import EmbeddedServletContainerFactory;import ;import uration;/** * Create by IntelliJ IDEA * * @author chenlei * @dateTime 2019/5/23 18:09 * @description TomcatConfig */@Configurationpublic class TomcatConfig { @Bean public EmbeddedServletContainerCustomizer containerCustomizer() { return new MyCustomizer(); } private static class MyCustomizer implements EmbeddedServletContainerCustomizer { @Override public void customize(ConfigurableEmbeddedServletContainer factory) { if (factory instanceof TomcatEmbeddedServletContainerFactory) { customizeTomcat((TomcatEmbeddedServletContainerFactory) factory); } } void customizeTomcat(TomcatEmbeddedServletContainerFactory factory) { nectorCustomizers((TomcatConnectorCustomizer) connector -> { ribute("relaxedPathChars", "<>[]^`{|}"); ribute("relaxedQueryChars", "<>[]^`{|}"); }); } }}springboot 2.x(2.1.3测试有效)import ConnectorCustomizer;import ServletWebServerFactory;import tWebServerFactory;import ;import uration;/** * Create by IntelliJ IDEA * * @author chenlei * @dateTime 2019/5/23 18:09 * @description TomcatConfig */@Configurationpublic class TomcatConfig { @Bean public ServletWebServerFactory webServerFactory() { TomcatServletWebServerFactory fa = new TomcatServletWebServerFactory(); nectorCustomizers((TomcatConnectorCustomizer) connector -> perty("relaxedQueryChars", "[]{}")); return fa; }}总结这次问题出现的原因是升级springboot导致的,因为之前使⽤的较低版本的springboot(E),升级到E后出现了该问题。因为之前在springboot 2.x上遇到过这个问题,因此知道问题所在,但springboot 1.x和2.x的解决⽅案有⼀点差异,这⾥记录⼀下。后续后⾯再做了⼀次Tomcat升级,从9.0.21升级到9.0.31,突然⼜出现这个问题,问题原因是⼀样的,tomcat对⾮法字符的控制更加严格了,严格遵循最新的RFC7230,我们除了把所有的⾮法字符全部加到relaxedQueryChars以外,还添加了另⼀项配置rejectIllegalHeader:@Configurationpublic class TomcatConfig { @Bean public ServletWebServerFactory webServerFactory() { TomcatServletWebServerFactory fa = new TomcatServletWebServerFactory(); nectorCustomizers(connector -> { perty("relaxedQueryChars", "(),/:;<=>?@[]{}"); perty("rejectIllegalHeader", "false"); }); return fa; }}关于这个配置的解释参考:rejectIllegalHeaderIf an HTTP request is received that contains an illegal header name or value (e.g. the header name is not a token) this setting determines if the request will be rejected with a 400response (true) or if the illegal header be ignored (false). The default value is true which will cause the request to be rejected.这样配置后(1.x的配置类似),⼤部分URI和Header都可以兼容,但是正如⽂档⾥所说的,rejectIllegalHeader会导致⾮法的header忽略,即header信息将不会被服务器接收。所以⼀旦Header⾥⾯有⾮法字符,对应的Header项将被忽略,服务器不会报400,但会跳过这个header项,⽐如升级过程中我们发现有API在header⾥传输中⽂,导致服务启报错,加了rejectIllegalHeader=false后,不报400,但程序找不到对应的Header,最后不得不删除这些不规范的header。以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持.

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1687678712a30873.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信