Describe the bug
SecurityMockMvcRequestPostProcessors.csrf() doesn't create correct token for XorCsrfTokenRequestAttributeHandler
Env - spring boot 3.0.9 - spring security 6.0.5
To Reproduce
XorCsrfTokenRequestAttributeHandler
// securityConfig.kt
@Bean
fun securityFilterChiain(http: HttpSecurity) : SecurityFilterChain {
http.run {
cors()
csrf { csrf ->
csrf.csrfTokenRepository(
CookieCsrfTokenRepository.withHttpOnlyFalse()
)
csrf.csrfTokenRequestHandler(XorCsrfTokenRequestAttributeHandler()::handle)
}
}
}
// securityConfigTest
@AutoWired
lateinit var mvc: MockMvc
@Test
fun testPostError() {
mvc.post("/error") {
requestAttr(RequestDispatcher.ERROR_STATUS_CODE, 500)
with(csrf())
}
.andDo { print() }
.andExpect {
status { isOk() }
jsonPath("$.status") { value(500) }
jsonPath("$.message") { exists() }
}
}
// result
// Status
// Expected :200
// Actual :403
CsrfTokenRequestAttributeHandler
// securityConfig.kt
@Bean
fun securityFilterChiain(http: HttpSecurity) : SecurityFilterChain {
http.run {
cors()
csrf { csrf ->
csrf.csrfTokenRepository(
CookieCsrfTokenRepository.withHttpOnlyFalse()
)
csrf.csrfTokenRequestHandler(CsrfTokenRequestAttributeHandler()::handle)
}
}
}
// securityConfigTest
@AutoWired
lateinit var mvc: MockMvc
@Test
fun testPostError() {
mvc.post("/error") {
requestAttr(RequestDispatcher.ERROR_STATUS_CODE, 500)
with(csrf())
}
.andDo { print() }
.andExpect {
status { isOk() }
jsonPath("$.status") { value(500) }
jsonPath("$.message") { exists() }
}
}
// result
// pass
// errorController.kt
@RequestMapping("/error")
fun handleError(request: HttpServletRequest, response: HttpServletResponse): String {
val statusCode = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE) as Int?
?: HttpStatus.OK.value()
val message = HttpStatus.valueOf(statusCode).reasonPhrase
"""{ "status": $statusCode, "message": "$message" }"""
}
Comment From: JinSeokO
same issue on stackoverflow: https://stackoverflow.com/questions/74729765/csrf-in-tests-stopped-working-with-spring-boot-3-and-spring-security-6