-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Add the ability to set the SameSite policy to the CRSF Cookie #12109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 6 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
b9cd4c3
Add the ability to set the SameSite policy to the CRSF Cookie
kumo829 777708d
- Remove un necessary new method to set same site policy.
kumo829 ad574a7
Merge branch 'main' into main
kumo829 825aefb
- Remove un necessary new method to set same site policy.
kumo829 62d1b40
- Remove un necessary new method to set same site policy.
kumo829 1b0dbb0
- Junit 5 cleanup removing public modifier in tests and classes
kumo829 58f14e4
Add a customizer to CookieCsrfTokenRepository and CookieServerCsrfTok…
kumo829 2b6b0a0
Merge branch 'spring-projects:main' into main
kumo829 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
package org.springframework.security.web.server.csrf; | ||
|
||
import java.util.UUID; | ||
import java.util.function.Consumer; | ||
|
||
import reactor.core.publisher.Mono; | ||
import reactor.core.scheduler.Schedulers; | ||
|
@@ -36,6 +37,7 @@ | |
* @author Eric Deandrea | ||
* @author Thomas Vitale | ||
* @author Alonso Araya | ||
* @author Alex Montoya | ||
* @since 5.1 | ||
*/ | ||
public final class CookieServerCsrfTokenRepository implements ServerCsrfTokenRepository { | ||
|
@@ -60,6 +62,18 @@ public final class CookieServerCsrfTokenRepository implements ServerCsrfTokenRep | |
|
||
private int cookieMaxAge = -1; | ||
|
||
private Consumer<ResponseCookie.ResponseCookieBuilder> cookieCustomizer = (builder) -> {}; | ||
|
||
/** | ||
* Add a {@link Consumer} for a {@code ResponseCookieBuilder} that will be invoked | ||
* for each cookie being built, just before the call to {@code build()}. | ||
* @param cookieCustomizer consumer for a cookie builder | ||
* @since 6.1 | ||
*/ | ||
public void setCookieCustomizer(Consumer<ResponseCookie.ResponseCookieBuilder> cookieCustomizer) { | ||
this.cookieCustomizer = cookieCustomizer; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please check for null. You can use |
||
} | ||
|
||
/** | ||
* Factory method to conveniently create an instance that has | ||
* {@link #setCookieHttpOnly(boolean)} set to false. | ||
|
@@ -82,16 +96,18 @@ public Mono<Void> saveToken(ServerWebExchange exchange, CsrfToken token) { | |
return Mono.fromRunnable(() -> { | ||
String tokenValue = (token != null) ? token.getToken() : ""; | ||
// @formatter:off | ||
ResponseCookie cookie = ResponseCookie | ||
ResponseCookie.ResponseCookieBuilder cookieBuilder = ResponseCookie | ||
.from(this.cookieName, tokenValue) | ||
.domain(this.cookieDomain) | ||
.httpOnly(this.cookieHttpOnly) | ||
.maxAge(!tokenValue.isEmpty() ? this.cookieMaxAge : 0) | ||
.path((this.cookiePath != null) ? this.cookiePath : getRequestContext(exchange.getRequest())) | ||
.secure((this.secure != null) ? this.secure : (exchange.getRequest().getSslInfo() != null)) | ||
.build(); | ||
.secure((this.secure != null) ? this.secure : (exchange.getRequest().getSslInfo() != null)); | ||
|
||
this.cookieCustomizer.accept(cookieBuilder); | ||
|
||
// @formatter:on | ||
exchange.getResponse().addCookie(cookie); | ||
exchange.getResponse().addCookie(cookieBuilder.build()); | ||
}); | ||
} | ||
|
||
|
@@ -107,9 +123,9 @@ public Mono<CsrfToken> loadToken(ServerWebExchange exchange) { | |
} | ||
|
||
/** | ||
* Sets the HttpOnly attribute on the cookie containing the CSRF token | ||
* @param cookieHttpOnly True to mark the cookie as http only. False otherwise. | ||
* @deprecated Use {@link #setCookieCustomizer(Consumer)} instead. | ||
*/ | ||
@Deprecated(since = "6.1") | ||
public void setCookieHttpOnly(boolean cookieHttpOnly) { | ||
this.cookieHttpOnly = cookieHttpOnly; | ||
} | ||
|
@@ -150,44 +166,27 @@ public void setCookiePath(String cookiePath) { | |
} | ||
|
||
/** | ||
* Sets the cookie domain | ||
* @param cookieDomain The cookie domain | ||
* @deprecated Use {@link #setCookieCustomizer(Consumer)} instead. | ||
*/ | ||
@Deprecated(since = "6.1") | ||
public void setCookieDomain(String cookieDomain) { | ||
this.cookieDomain = cookieDomain; | ||
} | ||
|
||
/** | ||
* Sets the cookie secure flag. If not set, the value depends on | ||
* {@link ServerHttpRequest#getSslInfo()}. | ||
* @param secure The value for the secure flag | ||
* @deprecated Use {@link #setCookieCustomizer(Consumer)} instead. | ||
* @since 5.5 | ||
*/ | ||
@Deprecated(since = "6.1") | ||
public void setSecure(boolean secure) { | ||
this.secure = secure; | ||
} | ||
|
||
/** | ||
* Sets maximum age in seconds for the cookie that the expected CSRF token is saved to | ||
* and read from. By default maximum age value is -1. | ||
* | ||
* <p> | ||
* A positive value indicates that the cookie will expire after that many seconds have | ||
* passed. Note that the value is the <i>maximum</i> age when the cookie will expire, | ||
* not the cookie's current age. | ||
* | ||
* <p> | ||
* A negative value means that the cookie is not stored persistently and will be | ||
* deleted when the Web browser exits. | ||
* | ||
* <p> | ||
* A zero value causes the cookie to be deleted immediately therefore it is not a | ||
* valid value and in that case an {@link IllegalArgumentException} will be thrown. | ||
* @param cookieMaxAge an integer specifying the maximum age of the cookie in seconds; | ||
* if negative, means the cookie is not stored; if zero, the method throws an | ||
* {@link IllegalArgumentException} | ||
* @deprecated Use {@link #setCookieCustomizer(Consumer)} instead. | ||
* @since 5.8 | ||
*/ | ||
@Deprecated(since = "6.1") | ||
public void setCookieMaxAge(int cookieMaxAge) { | ||
Assert.isTrue(cookieMaxAge != 0, "cookieMaxAge cannot be zero"); | ||
this.cookieMaxAge = cookieMaxAge; | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The indentation looks off here. Would you mind adjusting it, please?