Skip to content

Commit 2805f25

Browse files
Add spa() configuration method
Signed-off-by: Tran Ngoc Nhan <ngocnhan.tran1996@gmail.com>
1 parent 83f5dd0 commit 2805f25

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

  • config/src
    • main/kotlin/org/springframework/security/config/annotation/web
    • test/kotlin/org/springframework/security/config/annotation/web

config/src/main/kotlin/org/springframework/security/config/annotation/web/CsrfDsl.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class CsrfDsl {
4747
private var ignoringRequestMatchers: Array<out RequestMatcher>? = null
4848
private var ignoringRequestMatchersPatterns: Array<out String>? = null
4949
private var disabled = false
50+
private var spaMode = false
5051

5152
/**
5253
* Allows specifying [HttpServletRequest]s that should not use CSRF Protection
@@ -76,6 +77,17 @@ class CsrfDsl {
7677
disabled = true
7778
}
7879

80+
/**
81+
* Sensible CSRF defaults when used in combination with a single page application.
82+
* Creates a cookie-based token repository and a custom request handler to resolve the
83+
* actual token value instead of the encoded token.
84+
*
85+
* @since 7.1
86+
*/
87+
fun spa() {
88+
spaMode = true
89+
}
90+
7991
internal fun get(): (CsrfConfigurer<HttpSecurity>) -> Unit {
8092
return { csrf ->
8193
csrfTokenRepository?.also { csrf.csrfTokenRepository(csrfTokenRepository) }
@@ -84,6 +96,9 @@ class CsrfDsl {
8496
csrfTokenRequestHandler?.also { csrf.csrfTokenRequestHandler(csrfTokenRequestHandler) }
8597
ignoringRequestMatchers?.also { csrf.ignoringRequestMatchers(*ignoringRequestMatchers!!) }
8698
ignoringRequestMatchersPatterns?.also { csrf.ignoringRequestMatchers(*ignoringRequestMatchersPatterns!!) }
99+
if (spaMode) {
100+
csrf.spa()
101+
}
87102
if (disabled) {
88103
csrf.disable()
89104
}

config/src/test/kotlin/org/springframework/security/config/annotation/web/CsrfDslTests.kt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,4 +345,40 @@ class CsrfDslTests {
345345
return http.build()
346346
}
347347
}
348+
349+
@Test
350+
fun `POST when CSRF for SPA enabled and no CSRF token then forbidden`() {
351+
this.spring.register(CsrfSPAConfig::class.java).autowire()
352+
353+
this.mockMvc.post("/test1")
354+
.andExpect {
355+
status { isForbidden() }
356+
}
357+
}
358+
359+
@Test
360+
fun `POST when CSRF for SPA enabled and CSRF token then status OK`() {
361+
this.spring.register(CsrfSPAConfig::class.java, BasicController::class.java).autowire()
362+
363+
this.mockMvc.post("/test1") {
364+
with(csrf())
365+
}.andExpect {
366+
status { isOk() }
367+
}
368+
369+
}
370+
371+
@Configuration
372+
@EnableWebSecurity
373+
open class CsrfSPAConfig {
374+
@Bean
375+
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
376+
http {
377+
csrf {
378+
spa()
379+
}
380+
}
381+
return http.build()
382+
}
383+
}
348384
}

0 commit comments

Comments
 (0)