【问题标题】:Avoid file extension detection in Spring MVC request mapping with floating point number in URI避免在 Spring MVC 请求映射中使用 URI 中的浮点数检测文件扩展名
【发布时间】:2016-03-13 17:32:28
【问题描述】:

我使用 Spring Boot 来实现一个 REST 应用程序。我有一个像这样映射的资源

@RequestMapping(value = "/{fromLat}/{fromLon}/{toLat}/{toLon:.+}", method = {RequestMethod.GET},
        produces = {"application/json"})

因此路径包含坐标,请求看起来像这样

$ curl -I -X GET http://localhost:8085/foobar/53.481297/9.900539/53.491691/9.946046

不幸的是,最后一个结尾被解释为文件扩展名,导致响应头提供文件下载,而不仅仅是纯数据。

Content-Disposition: attachment;filename=f.txt

我认为我可以使用自定义 WebMvcConfigurerAdapter Bean(并且没有 @EnableWebMvc)注释来处理这种情况,就像 here 解释的那样。

public class CustomWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false);
    }
}

但这并不能解决问题。不幸的是,检测到的文件扩展名未修复 - 因此我无法使用修复扩展名的规则。

如何将系统配置为仅响应内容而没有 Content-Disposition 标头(导致下载 f.txt)?我不想在末尾使用斜线(“/”)。

我已经看过以下资源

【问题讨论】:

    标签: java spring-mvc spring-boot


    【解决方案1】:

    您是否尝试设置:

    1) Content-Disposition: inline; -> 你可以使用:

    return new ResponseEntity(body, headers, statusCode);并在标题中设置 Content-Disposition。 看这里: How to set 'Content-Disposition' and 'Filename' when using FileSystemResource to force a file download file?Return a stream with Spring MVC's ResponseEntity

    2) text/x-json - 在application/json 正式注册之前的 JSON 实验性 MIME 类型。

    @RequestMapping(value = "/{fromLat}/{fromLon}/{toLat}/{toLon:.+}", method = {RequestMethod.GET},
                    produces = {"text/x-json"})
    

    它将尝试显示内容而不是下载它。

    希望它会有所帮助。

    【讨论】:

    • 我不知道如何在 @RestController 中将 Content-Disposition 更改为内联。如果可行,那可能是个好主意。
    • 谢谢。目前,我宁愿不更改我的 @RequestMapping 方法以返回 ResponseEntity 对象,而不是我当前的自动转换为 JSON 的 foobar 对象。但如果我找不到任何其他选择,我可能会尝试一下。
    【解决方案2】:

    我遇到了与 here 所述类似的 Spring Boot 问题。

    对我有用的是以下配置:

    @Configuration
    public class WebMvcConfig extends WebMvcConfigurerAdapter {
    
        @Override
        public void configurePathMatch(PathMatchConfigurer configurer) {
            configurer.setUseSuffixPatternMatch(false);
    
        }
    
    
    }
    

    【讨论】:

    • 今天,对于您的 (Franz') 用例,我也建议这样做。不久前我遇到了类似的问题:我想在我的控制器方法中使用文件后缀(即 .jpg、.xml 等)(我知道“正确”的方法是通过不同的视图来处理)并且我解决了它使用我自己的路径匹配器:info.michael-simons.eu/2011/03/09/… 我想这也适用于 Boot
    • 不幸的是,这不起作用。请求与 Controller 方法不匹配不是问题,而是响应始终包含 Content-Disposition: attachment;filename=f.txt 标头,导致浏览器提供下载而不是仅显示 JSON 结果。
    • 我什至不想让我的CustomWebMvcConfigurerAdapter 成为@Configuration 课程。相反,我想遵循 Spring Boot documentation 中记录的建议:如果您想保留 Spring Boot MVC 功能,并且只想添加额外的 MVC 配置(拦截器、格式化程序、视图控制器等)您可以添加自己的 WebMvcConfigurerAdapter 类型的 @Bean,但不添加 @EnableWebMvc。
    • 您的控制器是否使用@RestController @Controller 注释?如果是第二个,请将“@ResponseBody”添加到您的方法注释中。
    【解决方案3】:

    在 Spring Framework 4.1.9 和 4.2.3 中,Content-Disposition 标头已修复为使用“内联”类型,该类型仅建议文件下载名称,以防内容最终被下载。它不会再强制出现另存为对话框。

    还要注意,Content-Disposition 标头首先是为了保护应用程序免受 RFD 攻击。这是一个非常复杂的问题,但您可以在CVE-2015-5211 报告中查看摘要。

    【讨论】:

    • 使用 Spring Framework 4.1.8 时仍然是 Content-Disposition: attachment;filename=f.txt(使用 Spring IO Platfrom 1.1.4 时),但使用 Spring IO Platform 2.0.0(使用 Spring Framework 4.2.3 时)肯定是 Content-Disposition: inline;filename=f.txt。升级是我的解决方案。谢谢!
    • 是的,确实是 4.1.9(今天发布)和 4.2.3 有修复。我已经在上面更新了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 2011-08-14
    • 2014-02-06
    相关资源
    最近更新 更多