mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-30 08:42:13 +00:00
Add reactive opt out steps for CSRF BREACH
Issue gh-11959
This commit is contained in:
parent
4994e67eda
commit
4442a618ea
@ -32,7 +32,7 @@ SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
|
|||||||
[source,kotlin,role="secondary"]
|
[source,kotlin,role="secondary"]
|
||||||
----
|
----
|
||||||
@Bean
|
@Bean
|
||||||
open fun securityWebFilterChain(http: HttpSecurity): SecurityWebFilterChain {
|
open fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
|
||||||
return http {
|
return http {
|
||||||
// ...
|
// ...
|
||||||
csrf {
|
csrf {
|
||||||
@ -67,7 +67,7 @@ SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
|
|||||||
[source,kotlin,role="secondary"]
|
[source,kotlin,role="secondary"]
|
||||||
----
|
----
|
||||||
@Bean
|
@Bean
|
||||||
open fun securityWebFilterChain(http: HttpSecurity): SecurityWebFilterChain {
|
open fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
|
||||||
val requestHandler = ServerCsrfTokenRequestAttributeHandler()
|
val requestHandler = ServerCsrfTokenRequestAttributeHandler()
|
||||||
requestHandler.tokenFromMultipartDataEnabled = true
|
requestHandler.tokenFromMultipartDataEnabled = true
|
||||||
return http {
|
return http {
|
||||||
@ -106,7 +106,7 @@ SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
|
|||||||
[source,kotlin,role="secondary"]
|
[source,kotlin,role="secondary"]
|
||||||
----
|
----
|
||||||
@Bean
|
@Bean
|
||||||
open fun securityWebFilterChain(http: HttpSecurity): SecurityWebFilterChain {
|
open fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
|
||||||
val requestHandler = XorServerCsrfTokenRequestAttributeHandler()
|
val requestHandler = XorServerCsrfTokenRequestAttributeHandler()
|
||||||
// ...
|
// ...
|
||||||
return http {
|
return http {
|
||||||
@ -119,6 +119,116 @@ open fun securityWebFilterChain(http: HttpSecurity): SecurityWebFilterChain {
|
|||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
|
[[reactive-csrf-breach-opt-out]]
|
||||||
|
=== Opt-out Steps
|
||||||
|
|
||||||
|
If configuring CSRF BREACH protection gives you trouble, take a look at these scenarios for optimal opt out behavior:
|
||||||
|
|
||||||
|
==== I am using AngularJS or another Javascript framework
|
||||||
|
|
||||||
|
If you are using AngularJS and the https://angular.io/api/common/http/HttpClientXsrfModule[HttpClientXsrfModule] (or a similar module in another framework) along with `CookieCsrfTokenRepository.withHttpOnlyFalse()`, you may find that automatic support no longer works.
|
||||||
|
|
||||||
|
In this case, you can configure Spring Security to validate the raw `CsrfToken` from the cookie while keeping CSRF BREACH protection of the response using a custom `ServerCsrfTokenRequestHandler` with delegation, like so:
|
||||||
|
|
||||||
|
.Configure `CsrfToken` BREACH Protection to validate raw tokens
|
||||||
|
====
|
||||||
|
.Java
|
||||||
|
[source,java,role="primary"]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
|
||||||
|
CookieServerCsrfTokenRepository tokenRepository = CookieServerCsrfTokenRepository.withHttpOnlyFalse();
|
||||||
|
XorServerCsrfTokenRequestAttributeHandler delegate = new XorServerCsrfTokenRequestAttributeHandler();
|
||||||
|
// Use only the handle() method of XorServerCsrfTokenRequestAttributeHandler and the
|
||||||
|
// default implementation of resolveCsrfTokenValue() from ServerCsrfTokenRequestHandler
|
||||||
|
ServerCsrfTokenRequestHandler requestHandler = delegate::handle;
|
||||||
|
http
|
||||||
|
// ...
|
||||||
|
.csrf((csrf) -> csrf
|
||||||
|
.csrfTokenRepository(tokenRepository)
|
||||||
|
.csrfTokenRequestHandler(requestHandler)
|
||||||
|
);
|
||||||
|
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
WebFilter csrfCookieWebFilter() {
|
||||||
|
return (exchange, chain) -> {
|
||||||
|
Mono<CsrfToken> csrfToken = exchange.getAttributeOrDefault(CsrfToken.class.getName(), Mono.empty());
|
||||||
|
return csrfToken.doOnSuccess(token -> {
|
||||||
|
/* Ensures the token is subscribed to. */
|
||||||
|
}).then(chain.filter(exchange));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
.Kotlin
|
||||||
|
[source,kotlin,role="secondary"]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
open fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
|
||||||
|
val tokenRepository = CookieServerCsrfTokenRepository.withHttpOnlyFalse()
|
||||||
|
val delegate = XorServerCsrfTokenRequestAttributeHandler()
|
||||||
|
// Use only the handle() method of XorCsrfTokenRequestAttributeHandler and the
|
||||||
|
// default implementation of resolveCsrfTokenValue() from CsrfTokenRequestHandler
|
||||||
|
val requestHandler = ServerCsrfTokenRequestHandler(delegate::handle)
|
||||||
|
return http.invoke {
|
||||||
|
// ...
|
||||||
|
csrf {
|
||||||
|
csrfTokenRepository = tokenRepository
|
||||||
|
csrfTokenRequestHandler = requestHandler
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun csrfCookieWebFilter(): WebFilter {
|
||||||
|
return WebFilter { exchange, chain ->
|
||||||
|
val csrfToken = exchange.getAttribute<Mono<CsrfToken>>(CsrfToken::class.java.name) ?: Mono.empty()
|
||||||
|
csrfToken.doOnSuccess { }.then(chain.filter(exchange))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
==== I need to opt out of CSRF BREACH protection for another reason
|
||||||
|
|
||||||
|
If CSRF BREACH protection does not work for you for another reason, you can opt out using the following configuration:
|
||||||
|
|
||||||
|
.Opt out of `CsrfToken` BREACH protection
|
||||||
|
====
|
||||||
|
.Java
|
||||||
|
[source,java,role="primary"]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
|
||||||
|
ServerCsrfTokenRequestAttributeHandler requestHandler = new ServerCsrfTokenRequestAttributeHandler();
|
||||||
|
http
|
||||||
|
// ...
|
||||||
|
.csrf((csrf) -> csrf
|
||||||
|
.csrfTokenRequestHandler(requestHandler)
|
||||||
|
);
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
.Kotlin
|
||||||
|
[source,kotlin,role="secondary"]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
open fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
|
||||||
|
val requestHandler = ServerCsrfTokenRequestAttributeHandler()
|
||||||
|
return http {
|
||||||
|
// ...
|
||||||
|
csrf {
|
||||||
|
csrfTokenRequestHandler = requestHandler
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
== Use `AuthorizationManager` for Method Security
|
== Use `AuthorizationManager` for Method Security
|
||||||
|
|
||||||
xref:reactive/authorization/method.adoc[Method Security] has been xref:reactive/authorization/method.adoc#jc-enable-reactive-method-security-authorization-manager[improved] through {security-api-url}org/springframework/security/authorization/AuthorizationManager.html[the `AuthorizationManager` API] and direct use of Spring AOP.
|
xref:reactive/authorization/method.adoc[Method Security] has been xref:reactive/authorization/method.adoc#jc-enable-reactive-method-security-authorization-manager[improved] through {security-api-url}org/springframework/security/authorization/AuthorizationManager.html[the `AuthorizationManager` API] and direct use of Spring AOP.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user