Skip to content

Commit 6ddb534

Browse files
committed
chore: Custom cooke resolver and logout on session invalidation
1 parent c417c30 commit 6ddb534

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.appsmith.server.configurations;
2+
3+
import org.springframework.web.server.ServerWebExchange;
4+
import org.springframework.web.server.session.CookieWebSessionIdResolver;
5+
6+
import java.time.Duration;
7+
8+
import static java.time.temporal.ChronoUnit.DAYS;
9+
10+
/**
11+
* This class is a custom implementation of the CookieWebSessionIdResolver class.
12+
* It allows us to set the SameSite attribute of the session cookie based on
13+
* the organization configuration for cross site embedding.
14+
*/
15+
public class CustomCookieWebSessionIdResolver extends CookieWebSessionIdResolver {
16+
17+
public static final String LAX = "Lax";
18+
19+
public CustomCookieWebSessionIdResolver() {
20+
// Set default cookie attributes
21+
22+
// Setting the max age to 30 days so that the cookie doesn't expire on browser close
23+
// If the max age is not set, some browsers will default to deleting the cookies on session close.
24+
this.setCookieMaxAge(Duration.of(30, DAYS));
25+
this.addCookieInitializer((builder) -> builder.path("/"));
26+
}
27+
28+
@Override
29+
public void setSessionId(ServerWebExchange exchange, String id) {
30+
// Add the appropriate SameSite attribute based on the exchange attribute
31+
addCookieInitializer((builder) -> builder.sameSite(LAX).secure(true));
32+
super.setSessionId(exchange, id);
33+
}
34+
}

app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SecurityConfig.java

+1-10
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,9 @@
5353
import org.springframework.web.server.ServerWebExchange;
5454
import org.springframework.web.server.WebFilterChain;
5555
import org.springframework.web.server.adapter.ForwardedHeaderTransformer;
56-
import org.springframework.web.server.session.CookieWebSessionIdResolver;
5756
import org.springframework.web.server.session.WebSessionIdResolver;
5857
import reactor.core.publisher.Mono;
5958

60-
import java.time.Duration;
6159
import java.util.HashSet;
6260
import java.util.List;
6361

@@ -73,7 +71,6 @@
7371
import static com.appsmith.server.constants.Url.USAGE_PULSE_URL;
7472
import static com.appsmith.server.constants.Url.USER_URL;
7573
import static com.appsmith.server.constants.ce.UrlCE.CONSOLIDATED_API_URL;
76-
import static java.time.temporal.ChronoUnit.DAYS;
7774

7875
@EnableWebFluxSecurity
7976
@EnableReactiveMethodSecurity
@@ -271,13 +268,7 @@ public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
271268
*/
272269
@Bean
273270
public WebSessionIdResolver webSessionIdResolver() {
274-
CookieWebSessionIdResolver resolver = new CookieWebSessionIdResolver();
275-
// Setting the max age to 30 days so that the cookie doesn't expire on browser close
276-
// If the max age is not set, some browsers will default to deleting the cookies on session close.
277-
resolver.setCookieMaxAge(Duration.of(30, DAYS));
278-
resolver.addCookieInitializer((builder) -> builder.path("/"));
279-
resolver.addCookieInitializer((builder) -> builder.sameSite("Lax"));
280-
return resolver;
271+
return new CustomCookieWebSessionIdResolver();
281272
}
282273

283274
private User createAnonymousUser() {

app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/GlobalExceptionHandler.java

+9
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ public class GlobalExceptionHandler {
5454

5555
private final SessionUserService sessionUserService;
5656

57+
@ExceptionHandler(IllegalStateException.class)
58+
public Mono<Void> handleSessionInvalidation(ServerWebExchange exchange, IllegalStateException ex) {
59+
if (ex.getMessage().contains("Session was invalidated")) {
60+
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
61+
return exchange.getResponse().setComplete();
62+
}
63+
return Mono.error(ex);
64+
}
65+
5766
/**
5867
* This function only catches the AppsmithException type and formats it into ResponseEntity<ErrorDTO> object
5968
* Ideally, we should only be throwing AppsmithException from our code. This ensures that we can standardize

0 commit comments

Comments
 (0)