Skip to content

Commit 3926a39

Browse files
Add spa() configuration method
Signed-off-by: Tran Ngoc Nhan <ngocnhan.tran1996@gmail.com>
1 parent 6d6552a commit 3926a39

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
@@ -343,4 +343,40 @@ class CsrfDslTests {
343343
return http.build()
344344
}
345345
}
346+
347+
@Test
348+
fun `POST when CSRF for SPA enabled and no CSRF token then forbidden`() {
349+
this.spring.register(CsrfSPAConfig::class.java).autowire()
350+
351+
this.mockMvc.post("/test1")
352+
.andExpect {
353+
status { isForbidden() }
354+
}
355+
}
356+
357+
@Test
358+
fun `POST when CSRF for SPA enabled and CSRF token then status OK`() {
359+
this.spring.register(CsrfSPAConfig::class.java, BasicController::class.java).autowire()
360+
361+
this.mockMvc.post("/test1") {
362+
with(csrf())
363+
}.andExpect {
364+
status { isOk() }
365+
}
366+
367+
}
368+
369+
@Configuration
370+
@EnableWebSecurity
371+
open class CsrfSPAConfig {
372+
@Bean
373+
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
374+
http {
375+
csrf {
376+
spa()
377+
}
378+
}
379+
return http.build()
380+
}
381+
}
346382
}

0 commit comments

Comments
 (0)