带有Spring RequestMapping路径参数的编码斜杠(%2F)提供HTTP 400

Jim*_*Jim 33 rest spring glassfish glassfish-3 spring-3

这不是重复引用的问题,因为它是特定于Spring的.无论谁添加了(事实发生3年后!)都没有费心去阅读问题或评论帖子,看看真正的答案是什么.接受的答案并不是答案,但答案的作者从未回过头来编辑它,就像我问的那样.

鉴于下面的restful方法,Spring 3.1给出了400错误,"客户端发送的请求在语法上是不正确的()".当token参数包含URL编码的斜杠(%2F)时,例如" https://somewhere.com/ws/stuff/lookup/resourceId/287559/token/R4o6lI%2FbBx43/userName/jim "没有%2F一切正常精细.第三方已经在调用此服务(当然!)因此我至少在短期内无法更改发送的内容.有关如何在服务器端解决此问题的任何想法?

这个问题在https://jira.springsource.org/browse/SPR-8662中得到了很好的描述,尽管这个问题与UriTemplate有关,我没有使用它,我可以说.

@RequestMapping("/ws/stuff/**")
@Controller
public class StuffController {
  @RequestMapping(value = "/ws/stuff/lookup/resourceId/{resourceId}/token/{token}/userName/{userName}", method = RequestMethod.GET)
   public @ResponseBody
   String provisionResource(@PathVariable("resourceId") String resourceId, @PathVariable("token") String token, @PathVariable("userName") String userName, ModelMap modelMap,
         HttpServletRequest request, HttpServletResponse response) {
      return handle(resourceId, userName, request, token, modelMap);
   }
}
Run Code Online (Sandbox Code Playgroud)

注意:这是在Glassfish 3.1.2上,最初是Grizzly/Glassfish不接受斜线,但是

-Dcom.sun.grizzly.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

修好了.

asadmin set configs.config.server-config.network-config.protocols.protocol.http-listener-2.http.encoded-slash-enabled=true

似乎没有帮助.

iam*_*ddy 17

对于spring-boot,以下是诀窍

@SpringBootApplication
public class Application extends WebMvcConfigurerAdapter {

    public static void main(String[] args) throws Exception {
        System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setUrlDecode(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 您还需要在Spring Boot 2中使用它:/sf/answers/3404573021/为了避免诸如`RequestRejectedException之类的错误:请求被拒绝,因为URL包含潜在的恶意字符串“%2F” ` (2认同)

Sol*_*ris 12

这可能是你的答案:urlencoded正斜杠正在打破URL

我建议不要把它放在路径中,而是将其移到请求参数中.

解决方法:

您可以将RequestMapping更改为

@RequestMapping(value = "/ws/stuff/lookup/resourceId/**", method = RequestMethod.GET) 
Run Code Online (Sandbox Code Playgroud)

然后从请求对象手动解析路径变量.

  • 它对我不起作用.即使使用"/**",如果%2F出现在路径中,我总是得到400. (4认同)

30t*_*thh 7

这是Spring 3.2.4的修复程序(也适用于其他版本).必须覆盖默认的UrlPathHelper

public class UrlPathHelperFixed extends UrlPathHelper {

    public UrlPathHelperFixed() {
        super.setUrlDecode(false);
    }

    @Override
    public void setUrlDecode(boolean urlDecode) {
        if (urlDecode) {
            throw new IllegalArgumentException("Handler [" + UrlPathHelperFixed.class.getName() + "] does not support URL decoding.");
        }
    }

    @Override
    public String getServletPath(HttpServletRequest request) {
        String servletPath = getOriginatingServletPath(request);
        return servletPath;
    }

    @Override
    public String getOriginatingServletPath(HttpServletRequest request) {
        String servletPath = request.getRequestURI().substring(request.getContextPath().length());
        return servletPath;
    }
}
Run Code Online (Sandbox Code Playgroud)

并将其注入Mapping Handler:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
    <property name="order" value="-1"></property>
    <property name="urlPathHelper">
        <bean class="com.yoochoose.frontend.spring.UrlPathHelperFixed"/>
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

经过一天的艰苦努力,它现在适合我:-)

有人建议Spring团队为https://jira.springsource.org/browse/SPR-11101


min*_*alf 7

2019 年 Spring Boot 2+/Spring(安全)5+/Java 8+ 更新:

由于我对iamiddy 答案的编辑被拒绝,我还想提供 Spring Boot 2 + 的完整解决方案作为单独的答案。

WebMvcConfigurerAdapter已被弃用与Spring5 / Java8并且可以与接口直接替换WebMvcConfigurer结束了:

@SpringBootApplication
public class Application extends WebMvcConfigurer {

    public static void main(String[] args) throws Exception {
        System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setUrlDecode(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,您还需要配置 Spring(Strict)HttpFirewall以避免阻塞带有错误消息的编码斜杠The request was rejected because the URL contained a potentially malicious String "%2F"

@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
    StrictHttpFirewall firewall = new StrictHttpFirewall();
    firewall.setAllowUrlEncodedSlash(true);    
    return firewall;
}
Run Code Online (Sandbox Code Playgroud)

Spring Boot 将HttpFirewall在可用时使用上述Bean - 否则可能需要WebSecurity按照此处所述进行配置:

  • @leonid 对我来说,它与 DECODE `connector -&gt;connector.setEncodedSolidusHandling(EncodedSolidusHandling.DECODE.getValue()));` 一起使用 (9认同)
  • 根据 [Tomcat 9 文档](https://tomcat.apache.org/tomcat-9.0-doc/config/systemprops.html),属性“UDecoder.ALLOW_ENCODED_SLASH”将被弃用。所以它可以是`@Bean``public WebServerFactoryCustomizer&lt;TomcatServletWebServerFactory&gt; tomcatCustomizer() {``返回工厂-&gt;factory.addConnectorCustomizers(``connector-&gt;connector.setEncodedSolidusHandling(PASS_THROUGH.getValue()));``}` (4认同)

yal*_*tem 7

Spring Boot 3.x / Tomcat 10.x 解决方案

感谢 @leonid 和 @Edu 的评论,我设法修复了 Tomcat 10.x,它删除了UDecoder.ALLOW_ENCODED_SLASH. 他们在发行说明中提到:

将系统属性 org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH 替换为连接器属性encodedSolidusHandling,该属性添加了一个附加选项,用于将 %2f 序列传递到应用程序,除了拒绝此类序列和解码此类序列之外,无需对其进行解码。(市场)

Spring 的等价物正是leonidEdu指出的:

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
        log.info("Configuring Tomcat to allow encoded slashes.");
        return factory -> factory.addConnectorCustomizers(connector -> connector.setEncodedSolidusHandling(
                EncodedSolidusHandling.DECODE.getValue()));
    }
Run Code Online (Sandbox Code Playgroud)


man*_*v07 6

对于春季启动应用程序,这对我有用..

版本1 添加

org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
Run Code Online (Sandbox Code Playgroud)

到您的application.properties文件

版本2 像这样运行你的spring启动应用程序.

static void main(String[] args) {
    System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
    SpringApplication.run this, args
}
Run Code Online (Sandbox Code Playgroud)

版本3或使用-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH = true运行您的Java应用程序

这个固定的%2F编码的斜杠路径变量对我来说.


小智 6

我找到了对我有用的解决方案。

System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
Run Code Online (Sandbox Code Playgroud)

就在springApplication.run(args);之前

并在Application类中添加以下代码

 @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setUrlDecode(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }
Run Code Online (Sandbox Code Playgroud)