代码之家  ›  专栏  ›  技术社区  ›  Greg Hill

Springboot不允许在URL中通过百分比和反斜杠。

  •  0
  • Greg Hill  · 技术社区  · 6 年前

    我们得到一个GET请求,它在URL中发送字符串字符,所以我们使用路径变量来接收它们。显然,调用服务无法更改其调用后端的方法,因此我们需要能够接受具有以下未编码字符的URL:

    发送百分号%时,返回HTTP 400。如果%后面的两个字符组成一个UTF编码字符

    反斜杠转换为正斜杠。我需要它保持反斜杠。

    我猜这些可能是Tomcat或servlet配置问题。

    (弹簧防尘套版本1.5.14.释放)

    3 回复  |  直到 5 年前
        1
  •  0
  •   Dimitri Mestdagh    6 年前

    如果正确的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) {
        // ...
    }
    

    另一种解决方案是使用完全不同的Web容器。例如,当使用jetty时,这根本不是问题,URL编码的斜杠和反斜杠都可以工作。

        2
  •  0
  •   aditya gupta    6 年前
    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;
                }
    

    我也遇到了类似的问题,我用过这个,希望这能有所帮助。

        3
  •  0
  •   Codo    6 年前

    您所体验的并不是特定于弹簧靴的。相反,它是对HTTP的限制。

    HTTP标准要求包含百分比字符的任何URL必须由Web服务器解码(cf第36页):

    如果请求URI是使用“%hex hex”编码[42]编码的,则 源服务器必须解码请求URI才能正确 解释请求。

    因此,无法可靠地转义斜线字符。

    因此,当在URL中使用斜杠时,无论是否使用编码,斜杠都将被视为路径分隔符。所以它不能用在弹簧引导路径变量中。百分号和反斜杠也存在类似的问题。

    最好的选择是使用查询参数或POST请求。

    在以下URL中,值 test_with_/and_% 传输:

    https://host/abc/def?text=test_with_%2F_and%25