这一部分是对 Spring 5 文档的直接翻译,连接是这个。这一部分的示例不再贴代码,请到这个项目的 mvc 分支下查看,本篇示例的控制器名称是 PathPatternController。
1)路径模式
除了 URI 模板,注解 @RequestMapping 和所有的组合 @RequestMapping 变种也支持 Ant 式的路径模式(例如:/myPath/*.do
)。URI 模板变量和 Ant 式的标记组合使用也是支持的(例如:/owners/*/pets/{petId}
)。
2)路径模式比较
当一个 URL 匹配多个模式时,会进行一次分类来寻找最佳匹配。
拥有数量最少的 URI 变量和通配符的匹配的路径模式被认为是最佳匹配。比如“/hotels/{hotel}/*
”有一个 URI 变量和一个通配符,而“/hotels/{hotel}/**
”有一个URI变量和量个通配符,所以前者被认为是最佳匹配。
如果两个模式有相同数量的通配符或URI变量,那么最长的那个被认为是最佳匹配。比如“/foo/bar*
”比“/foo/*
”长,所以前者是最佳匹配。
如果两个模式有相同数量的通配符或URI变量,且长度相同,那么通配符最少的那个被认为是最佳匹配。比如“/hotels/{hotel}
”相对于“/hotels/*
”是最佳匹配。
还有一些额外的特殊规则:
① 默认的映射模式“/**
”比任何其他匹配模式的优先级都低。比如:“/api/{a}/{b}/{c}
”的优先级高于“/**
”
② 前缀模式比如“/public/**
”的优先级低于任何其他的不包含双通配符的模式。比如“/public/path3/{a}/{b}/{c}
”的优先级更高。
全部的详细信息参见AntPathMatcher中的AntPatternComparator。注意,PathMatcher可以自定义(见“路径匹配”)。
3)带有占位符的路径模式
注解 @RequestMapping 中的模式支持对本地属性和/
或系统属性与环境变量使用${…}
占位符。这在控制器映射到的路径需要通过配置文件自定义的情形下会很有用。占位符的更多信息,可以去类 PropertyPlaceholderConfigurer
的 Javadoc 中查看。
4)后缀模式匹配
Spring MVC 默认执行“.*
”后缀匹配,所以一个映射到“/person
”的控制器隐式地映射到“/person.*
”。这让请求通过URL路径(比如/person.pdf
,/person.xml
)来获取资源很简单。
后缀模式匹配可以被关闭,或者把它限制到一组显式注册为协商好内容的路径扩展。这通常建议用于在普通请求映射中减少歧义,比如“/person/{id}
”中的一个点可能不代表文件扩展名,如“/person/joe@email.com
”和“/person/joe@email.com.json
”。而且,就像下面解释的那样,后缀模式匹配和内容协商可能被用在一些情形中来企图进行恶意攻击,所以有很好的理由来限制它们。
后缀匹配配置参见“路径匹配” ,内容协商配置参见“内容协商”。
5)后缀模式匹配和 RFD
反射型文件下载(Reflected file download:RFD)攻击在 2014 年最初由 Trustwave 在一篇论文中描述。这种袭击是类似于 XSS,因为它依赖于反映在响应中的输入(如查询参数,URI 变量)。不像在 HTML 中插入 JavaScript,一次 RFD 攻击依赖于浏览器执行一个下载并把响应当作可执行脚本来处理,就像双击了像拥有扩展名.bat
、.cmd
的文件。
在 Spring MV C中 @ResponseBody 和 ResponseEntity 的方法面临危险,因为它们可以渲染客户端能够通过 URL 路径扩展请求的不同类型的内容。注意到即不禁止后缀模式匹配也不单纯为内容协商目的禁止使用文件拓展名将有效防止 RFD 攻击。
为了全面防范 RFD 攻击,在渲染响应体之前,Spring MVC 添加了一个Content-Disposition:inline;filename=f.txt
响应头来暗示一个修正过的安全的下载文件。这仅在URL路径包含一个文件拓展名既不在白名单中,又没有因内容协商目的而显式注册时才这么做。当直接在浏览器中键入 URL 时,它可能会有副作用。
很多常用的路径扩展名默认在白名单中。此外,REST API 调用通常不是直接在浏览器中用作 URL 。使用自定义 HttpMessageConverter 实现的应用可以为内容协商显式注册文件扩展名,响应头 Content-Disposition 不会被添加到这样的扩展名中。参见“内容协商”。
这最初在CVE-2015-5211工作报告中引进。下面是这份报告的补充建议:
编写而非避开JSON 响应。这也是 OWASP XSS 中的建议。怎样用 Spring 这样做的例子见 spring-jackson-owasp。
配置后缀模式匹配为关闭的,或只限于使用显式注册的后缀。
配置内容协商时,设置属性 “useJaf” 和 “ignoreUnknownPathExtensions” 为 false,这样的话,如果URL中包含未知的扩展名,就会返回一个406错误。注意,如果 URL 可能会有一个点在结尾的话,这不是一个好的选择。
Add X-Content-Type-Options: nosniff header to responses. Spring Security 4 does this by default.
最后但同样重要的是,如有不准确的地方,请告知;水平有限,最后一句没有翻译,如有你有正确的理解,也请告知。邮箱:rocketeers@163.com