Spring Boot3+Spring Security6下测试中CSRF功能失效求助
问题:Spring Security CSRF配置导致单元测试失效
我们遇到Spring Security 6中CSRF保护适配问题,采用官方针对JavaScript框架的解决方案后,基于WebClient和FilterFunction的端到端测试恢复正常,但REST控制器的单元测试出现CSRF令牌不匹配错误,无法正常运行。使用Spring Boot 3之前的CSRF配置可让单元测试正常,但会导致端到端测试失败。
当前CSRF安全配置
// Enable CSRF security http.csrf { csrfConfigurer -> // 适配JavaScript框架的CSRF配置 val tokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse() val delegate = XorCsrfTokenRequestAttributeHandler() // 设置CsrfToken存入的请求属性名 delegate.setCsrfRequestAttributeName("_csrf") // 仅使用XorCsrfTokenRequestAttributeHandler的handle()方法,以及CsrfTokenRequestHandler默认的resolveCsrfTokenValue()实现 val requestHandler = CsrfTokenRequestHandler(delegate::handle) csrfConfigurer.csrfTokenRepository(tokenRepository) csrfConfigurer.csrfTokenRequestHandler(requestHandler) }
修复端到端测试的FilterFunction
override fun filter(request: ClientRequest, next: ExchangeFunction): Mono<ClientResponse> = next.exchange(request) .flatMap { response: ClientResponse -> if (response.statusCode().is4xxClientError) { val csrfCookie = response.cookies().getFirst("XSRF-TOKEN") if (csrfCookie != null) { val retryRequest: ClientRequest = ClientRequest.from(request) .headers { httpHeaders -> httpHeaders.set("X-XSRF-TOKEN", csrfCookie.value) } .cookies { cookies -> cookies.add("XSRF-TOKEN", csrfCookie.value) } .build() return@flatMap next.exchange(retryRequest) } } Mono.just(response) }
失效的单元测试代码
@Test fun `create tender with copyFrom null should succeed and return 201 and the uuid`() { mockMvc .perform( post("/api/my/endpoint") .param("title", "Angebot 1") .param("copyFrom", null) .with(user(tendererTestUsers[0])) .with(csrf()) ) .andExpectAll( status().isCreated, content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON), jsonPath("$", `is`(notNullValue())) ) }
问题现象
调试确认单元测试中存在CSRF令牌不匹配的问题,推测需要调整测试的CSRF配置,寻求修改思路。
内容的提问来源于stack exchange,提问作者Jan Kohnert
相关产品推荐
相关产品推荐

