提问人:Shaunyl 提问时间:11/3/2023 最后编辑:Shaunyl 更新时间:11/8/2023 访问量:43
我想在 webflux/kotlin/spring boot 3 应用程序中禁用 webhook 端点的 CSRF
I want to disable CSRF for a webhook endpoint in webflux/kotlin/spring boot 3 app
问:
我有以下代码:
@Bean
fun configure(http: ServerHttpSecurity): SecurityWebFilterChain {
// @formatter:off
return http
.authorizeExchange { it.pathMatchers(GET, *ALLOW_LIST_STATIC_RESOURCES).permitAll() }
.authorizeExchange { it.pathMatchers(GET, *ALLOW_LIST_VIEWS).permitAll() }
.authorizeExchange { it.pathMatchers(GET, *ALLOW_LIST_RESOURCES).permitAll() }
.authorizeExchange { it.pathMatchers(POST, *ALLOW_LIST_API_POST).permitAll() }
.authorizeExchange { it.pathMatchers(DELETE, *ALLOW_LIST_API_DELETE).permitAll() }
.formLogin { it.disable() }
.headers { headers -> headers.contentTypeOptions { } }
.headers { headers -> headers.frameOptions { it.mode(XFrameOptionsServerHttpHeadersWriter.Mode.DENY) } }
.headers { headers -> headers.xssProtection { it.disable() } }
.headers { headers -> headers.permissionsPolicy { it.policy("accelerometer=(), ambient-light-sensor=(), autoplay=(), camera=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), interest-cohort=(), magnetometer=(), microphone=(), midi=(), payment=(), usb=(), vr=(), xr-spatial-tracking=()") } }
.headers { headers -> headers.contentSecurityPolicy { it.policyDirectives(contentSecurityPolicy) } }
.build()
// @formatter:on
}
我只想为端点“/app/webhook”禁用 CSRF 保护,但我找不到方法。
我不能做:因为不存在。
我该怎么做?我希望 CSRF 适用于除该端点之外的所有端点。我认为 Spring 默认对所有修改调用(不包括 GET)应用 CSRF 保护,因此这些 webhook 调用将被阻止,因为它们来自外部提供商。
内部使用也不起作用。.csrf { it.ignoringAntMatchers("/app/webhook") }
ignoringAntMatchers
NegatedServerWebExchangeMatcher
csrf.requireCsrfProtectionMatcher
感谢您的帮助。
编辑1:
如果我使用此代码:
.csrf { csrf ->
csrf.requireCsrfProtectionMatcher(disabledUrlForCSRF()) }.build()
fun disabledUrlForCSRF(): AndServerWebExchangeMatcher = AndServerWebExchangeMatcher(
CsrfWebFilter.DEFAULT_CSRF_MATCHER,
NegatedServerWebExchangeMatcher(
ServerWebExchangeMatchers.pathMatchers(POST, "/app/webhook")
)
它有效
编辑2:
我也通过这样写它来使它工作(为了清楚起见,稍微清理了一下):
@Bean
fun configure(http: ServerHttpSecurity): SecurityWebFilterChain {
// @formatter:off
return http
.securityMatcher(
isNot( ServerWebExchangeMatchers.pathMatchers(POST,"/app/webhook")
)
)
.authorizeExchange { it.pathMatchers(OPTIONS).permitAll() }
.authorizeExchange { it.pathMatchers(POST, *ALLOW_LIST_API_POST).permitAll() }
.authorizeExchange { it.pathMatchers(DELETE, *ALLOW_LIST_API_DELETE).permitAll() }
.authorizeExchange { it.pathMatchers(GET).permitAll() }
.authorizeExchange { it.anyExchange().denyAll() }
.httpBasic { it.disable() }
.formLogin { it.disable() }.securityContextRepository(NoOpServerSecurityContextRepository.getInstance())
.build()
// @formatter:on
}
fun isNot(matcher: ServerWebExchangeMatcher): ServerWebExchangeMatcher {
return NegatedServerWebExchangeMatcher(matcher)
}
这里有三件重要的事情:
- 如果启用了 CSRF(因此没有 csrf.disable()),即使我明确告诉他不要使用 NoOpServerSecurityContextRepository 这样做,它也会创建一个 SESSION cookie。
- 我添加了所有端点上的 GET 匹配器,以将用户重定向到自定义错误页面,以防用户浏览到不存在的页面,例如,仅使用该行时不会发生这种情况。
permitAll()
anyExchange().denyAll()
但这些与主题无关。
谢谢。
答: 暂无答案
评论
formLogin()