12306网站开发时间,北京北京网站建设,建设局办的焊工证全国通用吗,建设银行秋招网站一、HttpFirewall
Spring Security有几个领域#xff0c;你所定义的 pattern 会针对传入的请求进行测试#xff0c;以决定应该如何处理请求。这发生在 FilterChainProxy 决定请求应该通过哪个过滤链时#xff0c;以及 FilterSecurityInterceptor 决定哪些安全约束适用于请求…
一、HttpFirewall
Spring Security有几个领域你所定义的 pattern 会针对传入的请求进行测试以决定应该如何处理请求。这发生在 FilterChainProxy 决定请求应该通过哪个过滤链时以及 FilterSecurityInterceptor 决定哪些安全约束适用于请求时。在针对你定义的 pattern 进行测试时了解该机制是什么以及使用什么URL值是很重要的。
servlet规范为 HttpServletRequest 定义了几个属性这些属性可以通过 getter 方法访问我们可能想与之匹配。这些属性是 contextPath、servletPath、pathInfo 和 queryString。Spring Security 只对应用程序中的路径安全感兴趣所以 contextPath 被忽略了。不幸的是servlet规范并没有准确地定义 servletPath 和 pathInfo 的值对于一个特定的请求URI包含什么。例如URL的每个路径段都可能包含参数正如 RFC 2396 所定义的那样你可能已经看到当浏览器不支持cookies时jsessionid 参数被附加到URL的分号之后。然而RFC允许在URL的任何路径段中出现这些参数。该规范没有明确说明这些参数是否应该包含在 servletPath 和 pathInfo 的值中而且不同的servlet容器之间的行为也不同。存在这样一种危险当应用程序部署在不从这些值中剥离路径参数的容器中时攻击者可以将它们添加到请求的 URL 中从而导致 pattern 匹配意外地成功或失败。一旦请求离开 FilterChainProxy原始值将被返回所以应用程序仍然可以使用。传入的URL也有可能出现其他变化。例如它可能包含路径遍历序列如 /../或多个正斜杠//也可能导致 pattern 匹配失败。一些容器在执行servlet映射之前会将这些内容规范化但其他容器则不会。为了防止类似的问题FilterChainProxy 使用 HttpFirewall 策略来检查和包装请求。默认情况下未规范化的请求会被自动拒绝路径参数和重复的斜线也会被删除以便匹配。因此例如一个原始的请求路径为 /secure;hack1/somefile.html;hack2被返回为 /secure/somefile.html。因此必须使用 FilterChainProxy 来管理安全过滤器链。请注意 servletPath 和 pathInfo 的值是由容器解码的所以你的应用程序不应该有任何包含分号的有效路径因为这些部分会被移除用于匹配目的。
如前所述默认策略是使用 Ant 风格的路径进行匹配这可能是大多数用户的最佳选择。该策略在 AntPathRequestMatcher 类中实现该类使用Spring的 AntPathMatcher对servletPath 和 pathInfo 的连接模式进行不区分大小写的匹配忽略 queryString。
如果你需要一个更强大的匹配策略你可以使用正则表达式。那么这个策略的实现就是 RegexRequestMatcher。参见 该类的Javadoc以了解更多信息。
在实践中我们建议你在服务层使用方法安全以控制对你的应用程序的访问而不是完全依赖使用在Web应用层定义的安全约束。URL会发生变化而且很难考虑到一个应用程序可能支持的所有可能的URL以及请求可能被操纵的方式。你应该限制自己使用一些简单的Ant路径这些路径很容易理解。始终尝试使用 “deny-by-default” 的方法在这里你有一个万能的通配符/** 或 **最后定义来拒绝访问。
在服务层定义的安全更强大更难绕过所以你应该始终利用Spring Security的方法安全选项。
HttpFirewall 还通过拒绝HTTP响应头中的换行字符来防止 HTTP响应分裂。
默认情况下使用 StrictHttpFirewall 实现。这个实现会拒绝那些看起来是恶意的请求。如果它对你的需求来说过于严格你可以自定义拒绝哪些类型的请求。然而重要的是你要知道这样做会使你的应用程序受到攻击。例如如果你希望使用Spring MVC的 matrix 变量你可以使用以下配置。
Allow Matrix Variables
Java
Bean
public StrictHttpFirewall httpFirewall() {StrictHttpFirewall firewall new StrictHttpFirewall();firewall.setAllowSemicolon(true);return firewall;
}
为了防止 跨站追踪XST 和 HTTP Verb TamperingStrictHttpFirewall 提供了一个允许的有效 HTTP 方法列表。默认的有效方法是 DELETE、GET、HEAD、OPTIONS、PATCH、POST 和 PUT。如果你的应用程序需要修改有效方法你可以配置一个自定义的 StrictHttpFirewall Bean。下面的例子只允许HTTP GET 和 POST 方法。
Allow Only GET POST
Java
Bean
public StrictHttpFirewall httpFirewall() {StrictHttpFirewall firewall new StrictHttpFirewall();firewall.setAllowedHttpMethods(Arrays.asList(GET, POST));return firewall;
} 如果你使用 new MockHttpServletRequest()它目前创建的HTTP方法是一个空字符串。这是一个无效的HTTP方法会被Spring Security拒绝。你可以用 new MockHttpServletRequest(GET, ) 代替它来解决这个问题。请参阅 SPR_16851该问题要求改进这一点。
如果你必须允许任何 HTTP 方法不推荐你可以使用 StrictHttpFirewall.setUnsafeAllowAnyHttpMethod(true)。这样做可以完全禁止对HTTP方法的验证。
StrictHttpFirewall 还检查头名称和值以及参数名称。它要求每个字符都有一个定义好的码位code point并且不是一个控制字符。
这一要求可以通过以下方法在必要时放宽或调整。
StrictHttpFirewall#setAllowedHeaderNames(Predicate)StrictHttpFirewall#setAllowedHeaderValues(Predicate)StrictHttpFirewall#setAllowedParameterNames(Predicate) 参数值也可以用 setAllowedParameterValues(Predicate) 来控制。
例如为了关闭这个检查你可以在你的 StrictHttpFirewall 中加入总是返回 true 的 Predicate 实例。
Allow Any Header Name, Header Value, and Parameter Name
Java
Bean
public StrictHttpFirewall httpFirewall() {StrictHttpFirewall firewall new StrictHttpFirewall();firewall.setAllowedHeaderNames((header) - true);firewall.setAllowedHeaderValues((header) - true);firewall.setAllowedParameterNames((parameter) - true);return firewall;
}
另外可能有一个特定的值你需要允许。
例如iPhone Xʀ 使用的 User-Agent 包括一个不属于 ISO-8859-1 字符集的字符。由于这一事实一些应用服务器将这个值解析为两个独立的字符后者是一个未定义的字符。
你可以用 setAllowedHeaderValues 方法解决这个问题。
Allow Certain User Agents
Java
Bean
public StrictHttpFirewall httpFirewall() {StrictHttpFirewall firewall new StrictHttpFirewall();Pattern allowed Pattern.compile([\\p{IsAssigned}[^\\p{IsControl}]]*);Pattern userAgent ...;firewall.setAllowedHeaderValues((header) - allowed.matcher(header).matches() || userAgent.matcher(header).matches());return firewall;
}
如果是 header 值你可以考虑在验证时将其解析为UTF-8。
Parse Headers As UTF-8
Java
firewall.setAllowedHeaderValues((header) - {String parsed new String(header.getBytes(ISO_8859_1), UTF_8);return allowed.matcher(parsed).matches();
}); 二、重定向到 HTTPS
如果客户端使用HTTP而不是HTTPS发出请求你可以配置Spring Security重定向到HTTPS。
例如下面的Java或Kotlin配置将任何HTTP请求重定向到HTTPS。
Redirect to HTTPS Java
Configuration
EnableWebSecurity
public class WebSecurityConfig {Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http// ....requiresChannel(channel - channel.anyRequest().requiresSecure());return http.build();}
}
下面的XML配置将所有HTTP请求重定向到HTTPS
Redirect to HTTPS with XML Configuration
httpintercept-url pattern/** accessROLE_USER requires-channelhttps/
...
/http