Add hook for customizing response cookie
Issue: SPR-16980
This commit is contained in:
parent
5ec8db1adc
commit
51ec7c6b4a
|
|
@ -19,6 +19,7 @@ package org.springframework.web.server.session;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.springframework.http.HttpCookie;
|
import org.springframework.http.HttpCookie;
|
||||||
|
|
@ -43,6 +44,9 @@ public class CookieWebSessionIdResolver implements WebSessionIdResolver {
|
||||||
|
|
||||||
private String sameSite = "Strict";
|
private String sameSite = "Strict";
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Consumer<ResponseCookie.ResponseCookieBuilder> cookieInitializer = null;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the name of the cookie to use for the session id.
|
* Set the name of the cookie to use for the session id.
|
||||||
|
|
@ -98,6 +102,19 @@ public class CookieWebSessionIdResolver implements WebSessionIdResolver {
|
||||||
return this.sameSite;
|
return this.sameSite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add {@link Consumer} for a {@link ResponseCookie.ResponseCookieBuilder
|
||||||
|
* ResponseCookieBuilder} that will be invoked for each cookie being built,
|
||||||
|
* just before the call to
|
||||||
|
* {@link ResponseCookie.ResponseCookieBuilder#build() build()}.
|
||||||
|
* @param initializer consumer for a cookie builder
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public void addCookieInitializer(Consumer<ResponseCookie.ResponseCookieBuilder> initializer) {
|
||||||
|
this.cookieInitializer = this.cookieInitializer != null ?
|
||||||
|
this.cookieInitializer.andThen(initializer) : initializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> resolveSessionIds(ServerWebExchange exchange) {
|
public List<String> resolveSessionIds(ServerWebExchange exchange) {
|
||||||
|
|
@ -125,13 +142,18 @@ public class CookieWebSessionIdResolver implements WebSessionIdResolver {
|
||||||
private ResponseCookie initSessionCookie(
|
private ResponseCookie initSessionCookie(
|
||||||
ServerWebExchange exchange, String id, Duration maxAge, @Nullable String sameSite) {
|
ServerWebExchange exchange, String id, Duration maxAge, @Nullable String sameSite) {
|
||||||
|
|
||||||
return ResponseCookie.from(this.cookieName, id)
|
ResponseCookie.ResponseCookieBuilder cookieBuilder = ResponseCookie.from(this.cookieName, id)
|
||||||
.path(exchange.getRequest().getPath().contextPath().value() + "/")
|
.path(exchange.getRequest().getPath().contextPath().value() + "/")
|
||||||
.maxAge(maxAge)
|
.maxAge(maxAge)
|
||||||
.httpOnly(true)
|
.httpOnly(true)
|
||||||
.secure("https".equalsIgnoreCase(exchange.getRequest().getURI().getScheme()))
|
.secure("https".equalsIgnoreCase(exchange.getRequest().getURI().getScheme()))
|
||||||
.sameSite(sameSite)
|
.sameSite(sameSite);
|
||||||
.build();
|
|
||||||
|
if (this.cookieInitializer != null) {
|
||||||
|
this.cookieInitializer.accept(cookieBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cookieBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,4 +46,22 @@ public class CookieWebSessionIdResolverTests {
|
||||||
assertNotNull(cookie);
|
assertNotNull(cookie);
|
||||||
assertEquals("SESSION=123; Path=/; Secure; HttpOnly; SameSite=Strict", cookie.toString());
|
assertEquals("SESSION=123; Path=/; Secure; HttpOnly; SameSite=Strict", cookie.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cookieInitializer() {
|
||||||
|
this.resolver.addCookieInitializer(builder -> builder.domain("example.org"));
|
||||||
|
this.resolver.addCookieInitializer(builder -> builder.sameSite("Lax"));
|
||||||
|
this.resolver.addCookieInitializer(builder -> builder.secure(false));
|
||||||
|
|
||||||
|
MockServerHttpRequest request = MockServerHttpRequest.get("https://example.org/path").build();
|
||||||
|
MockServerWebExchange exchange = MockServerWebExchange.from(request);
|
||||||
|
this.resolver.setSessionId(exchange, "123");
|
||||||
|
|
||||||
|
MultiValueMap<String, ResponseCookie> cookies = exchange.getResponse().getCookies();
|
||||||
|
assertEquals(1, cookies.size());
|
||||||
|
ResponseCookie cookie = cookies.getFirst(this.resolver.getCookieName());
|
||||||
|
assertNotNull(cookie);
|
||||||
|
assertEquals("SESSION=123; Path=/; Domain=example.org; HttpOnly; SameSite=Lax", cookie.toString());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue