我正在尝试添加我的自定义StrictHttpFirewall,以便在标头不匹配我的模式的情况下拒绝请求。
Spring安全配置如下:
@Configuration
@EnableWebSecurity
class SecurityConfig {
companion object {
private val HEADER_NAME_PATTERN = "^[a-z1-9_-]{1,512}$".toRegex(RegexOption.IGNORE_CASE)
private val HEADER_VALUE_BASE_PATTERN = "[\\p{IsAssigned}&&[^\\p{IsControl}]]*".toRegex()
private val HEADER_VALUE_ERROR_PATTERN = "[<>]".toRegex()
}
@Bean
fun requestRejectedHandler(): RequestRejectedHandler = ErrorResponseRequestRejectedHandler()
@Bean
fun httpFirewall(): HttpFirewall {
val firewall = StrictHttpFirewall()
val headerNames = { header: String -> HEADER_NAME_PATTERN.matches(header) }
val headerValues = { value: String ->
HEADER_VALUE_BASE_PATTERN.containsMatchIn(value).and(
!HEADER_VALUE_ERROR_PATTERN.containsMatchIn(value)
)
}
firewall.setAllowedHeaderNames(headerNames)
firewall.setAllowedHeaderValues(headerValues)
firewall.setAllowedHttpMethods(
listOf(GET.name(), POST.name(), PUT.name(), PATCH.name(), DELETE.name())
)
return firewall
}
@Bean
@Throws(Exception::class)
fun filterChain(http: HttpSecurity): SecurityFilterChain =
http
.authorizeHttpRequests { it.anyRequest().permitAll() }
.sessionManagement {
it
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.disable()
}
.headers {
it
.frameOptions { option -> option.sameOrigin() }
.xssProtection(Customizer.withDefaults())
.cacheControl { cache -> cache.disable() }
.contentSecurityPolicy(Customizer.withDefaults())
}
.cors { it.disable() }
.csrf { it.disable() }
.requestCache { it.disable() }
.build()
}
但不幸的是,它不工作,我仍然能够通过头部,是不匹配我的正则表达式。我有一个很长的调试会话,它看起来像是request本身(由mockMVC制作)拥有所有的头,但是spring security并没有检查request本身的头。有趣的提示:它正在验证我在控制器方法参数级别上指定为强制性的头-如@RequestHeader(value =“my-header”,required = true)。会很感激任何帮助。
已尝试:
1.将httpFirewall显式设置为WebSecurity -未成功
1.添加了自定义过滤器来调试头文件,结果头文件名被验证,但这只是因为我显式调用了request.headerNames.toList()
,因为请求本身在内部被HttpFirewallRequest实现 Package ,这已经用我实际期望的验证覆盖了方法getHeaders
。
1.不仅从mockMvc
而且从RestTemplate
发出请求,并且通过 Postman 发出请求-不成功
1条答案
按热度按时间b91juud31#
StrictHttpFirewall
检查头,但懒惰。另外,您必须注意,StrictHttpFirewall
将请求和响应都 Package 到Wrapper
中。这样,
StrictHttpFirewall
实际上不会拒绝请求,除非在filterChain
下面,请求访问黑名单中的一个头。这意味着即使你有一个被列入黑名单的标头,但过滤器链或控制器中没有人试图从该标头读取,你的请求也不会被拒绝,直到它被尝试读取。在引入此类保护的PR中,讨论了与此类报头检查的性能相关的问题,因为该检查将执行多次。
为了满足您的要求,我认为
StrictHttpFirewall
无法处理此问题。要急切地拒绝一个请求,你必须写一个过滤器,它位于过滤器链的开始,或者mvc层,检查是否存在这样的头并拒绝它。在过滤器链中引入请求的一个好处是,
FilterChainProxy
接受一个RequestReject(ed)Handler
,如果你选择抛出它,它将能够处理RequestReject(ed)Exception
。