From 6ddb534820813ce8cf08ade05d5f4d5f4a81814e Mon Sep 17 00:00:00 2001 From: Nidhi Nair Date: Wed, 12 Mar 2025 18:24:40 +0530 Subject: [PATCH 1/3] chore: Custom cooke resolver and logout on session invalidation --- .../CustomCookieWebSessionIdResolver.java | 34 +++++++++++++++++++ .../server/configurations/SecurityConfig.java | 11 +----- .../exceptions/GlobalExceptionHandler.java | 9 +++++ 3 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CustomCookieWebSessionIdResolver.java diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CustomCookieWebSessionIdResolver.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CustomCookieWebSessionIdResolver.java new file mode 100644 index 00000000000..c542c27f446 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CustomCookieWebSessionIdResolver.java @@ -0,0 +1,34 @@ +package com.appsmith.server.configurations; + +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.session.CookieWebSessionIdResolver; + +import java.time.Duration; + +import static java.time.temporal.ChronoUnit.DAYS; + +/** + * This class is a custom implementation of the CookieWebSessionIdResolver class. + * It allows us to set the SameSite attribute of the session cookie based on + * the organization configuration for cross site embedding. + */ +public class CustomCookieWebSessionIdResolver extends CookieWebSessionIdResolver { + + public static final String LAX = "Lax"; + + public CustomCookieWebSessionIdResolver() { + // Set default cookie attributes + + // Setting the max age to 30 days so that the cookie doesn't expire on browser close + // If the max age is not set, some browsers will default to deleting the cookies on session close. + this.setCookieMaxAge(Duration.of(30, DAYS)); + this.addCookieInitializer((builder) -> builder.path("/")); + } + + @Override + public void setSessionId(ServerWebExchange exchange, String id) { + // Add the appropriate SameSite attribute based on the exchange attribute + addCookieInitializer((builder) -> builder.sameSite(LAX).secure(true)); + super.setSessionId(exchange, id); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SecurityConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SecurityConfig.java index 8143204515a..9f787fd2676 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SecurityConfig.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SecurityConfig.java @@ -53,11 +53,9 @@ import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilterChain; import org.springframework.web.server.adapter.ForwardedHeaderTransformer; -import org.springframework.web.server.session.CookieWebSessionIdResolver; import org.springframework.web.server.session.WebSessionIdResolver; import reactor.core.publisher.Mono; -import java.time.Duration; import java.util.HashSet; import java.util.List; @@ -73,7 +71,6 @@ import static com.appsmith.server.constants.Url.USAGE_PULSE_URL; import static com.appsmith.server.constants.Url.USER_URL; import static com.appsmith.server.constants.ce.UrlCE.CONSOLIDATED_API_URL; -import static java.time.temporal.ChronoUnit.DAYS; @EnableWebFluxSecurity @EnableReactiveMethodSecurity @@ -271,13 +268,7 @@ public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { */ @Bean public WebSessionIdResolver webSessionIdResolver() { - CookieWebSessionIdResolver resolver = new CookieWebSessionIdResolver(); - // Setting the max age to 30 days so that the cookie doesn't expire on browser close - // If the max age is not set, some browsers will default to deleting the cookies on session close. - resolver.setCookieMaxAge(Duration.of(30, DAYS)); - resolver.addCookieInitializer((builder) -> builder.path("/")); - resolver.addCookieInitializer((builder) -> builder.sameSite("Lax")); - return resolver; + return new CustomCookieWebSessionIdResolver(); } private User createAnonymousUser() { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/GlobalExceptionHandler.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/GlobalExceptionHandler.java index 9c73bd56394..5356b2e190b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/GlobalExceptionHandler.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/GlobalExceptionHandler.java @@ -54,6 +54,15 @@ public class GlobalExceptionHandler { private final SessionUserService sessionUserService; + @ExceptionHandler(IllegalStateException.class) + public Mono handleSessionInvalidation(ServerWebExchange exchange, IllegalStateException ex) { + if (ex.getMessage().contains("Session was invalidated")) { + exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); + return exchange.getResponse().setComplete(); + } + return Mono.error(ex); + } + /** * This function only catches the AppsmithException type and formats it into ResponseEntity object * Ideally, we should only be throwing AppsmithException from our code. This ensures that we can standardize From f8dc52b458d892e613dc1430694f499d33434cd5 Mon Sep 17 00:00:00 2001 From: Nidhi Nair Date: Wed, 12 Mar 2025 19:51:00 +0530 Subject: [PATCH 2/3] Conducive to splitting --- .../CustomCookieWebSessionIdResolver.java | 28 +------------- .../CustomCookieWebSessionIdResolverCE.java | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+), 26 deletions(-) create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/ce/CustomCookieWebSessionIdResolverCE.java diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CustomCookieWebSessionIdResolver.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CustomCookieWebSessionIdResolver.java index c542c27f446..1a3f77688f3 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CustomCookieWebSessionIdResolver.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CustomCookieWebSessionIdResolver.java @@ -1,34 +1,10 @@ package com.appsmith.server.configurations; -import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.session.CookieWebSessionIdResolver; - -import java.time.Duration; - -import static java.time.temporal.ChronoUnit.DAYS; +import com.appsmith.server.configurations.ce.CustomCookieWebSessionIdResolverCE; /** * This class is a custom implementation of the CookieWebSessionIdResolver class. * It allows us to set the SameSite attribute of the session cookie based on * the organization configuration for cross site embedding. */ -public class CustomCookieWebSessionIdResolver extends CookieWebSessionIdResolver { - - public static final String LAX = "Lax"; - - public CustomCookieWebSessionIdResolver() { - // Set default cookie attributes - - // Setting the max age to 30 days so that the cookie doesn't expire on browser close - // If the max age is not set, some browsers will default to deleting the cookies on session close. - this.setCookieMaxAge(Duration.of(30, DAYS)); - this.addCookieInitializer((builder) -> builder.path("/")); - } - - @Override - public void setSessionId(ServerWebExchange exchange, String id) { - // Add the appropriate SameSite attribute based on the exchange attribute - addCookieInitializer((builder) -> builder.sameSite(LAX).secure(true)); - super.setSessionId(exchange, id); - } -} +public class CustomCookieWebSessionIdResolver extends CustomCookieWebSessionIdResolverCE {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/ce/CustomCookieWebSessionIdResolverCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/ce/CustomCookieWebSessionIdResolverCE.java new file mode 100644 index 00000000000..9ec2e960075 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/ce/CustomCookieWebSessionIdResolverCE.java @@ -0,0 +1,38 @@ +package com.appsmith.server.configurations.ce; + +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.session.CookieWebSessionIdResolver; + +import java.time.Duration; + +import static java.time.temporal.ChronoUnit.DAYS; + +/** + * This class is a custom implementation of the CookieWebSessionIdResolver class. + * It allows us to set the SameSite attribute of the session cookie based on + * the organization configuration for cross site embedding. + */ +public class CustomCookieWebSessionIdResolverCE extends CookieWebSessionIdResolver { + + public static final String LAX = "Lax"; + + public CustomCookieWebSessionIdResolverCE() { + // Set default cookie attributes + + // Setting the max age to 30 days so that the cookie doesn't expire on browser close + // If the max age is not set, some browsers will default to deleting the cookies on session close. + this.setCookieMaxAge(Duration.of(30, DAYS)); + this.addCookieInitializer((builder) -> builder.path("/")); + } + + @Override + public void setSessionId(ServerWebExchange exchange, String id) { + addCookieInitializer(); + super.setSessionId(exchange, id); + } + + protected void addCookieInitializer() { + // Add the appropriate SameSite attribute based on the exchange attribute + addCookieInitializer((builder) -> builder.sameSite(LAX).secure(true)); + } +} From 888e9daf3c84bef2c6d03b2ad5beb1a595e6a323 Mon Sep 17 00:00:00 2001 From: Nidhi Nair Date: Wed, 12 Mar 2025 19:52:03 +0530 Subject: [PATCH 3/3] Conducive to splitting --- .../configurations/ce/CustomCookieWebSessionIdResolverCE.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/ce/CustomCookieWebSessionIdResolverCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/ce/CustomCookieWebSessionIdResolverCE.java index 9ec2e960075..481a94d50bb 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/ce/CustomCookieWebSessionIdResolverCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/ce/CustomCookieWebSessionIdResolverCE.java @@ -27,11 +27,11 @@ public CustomCookieWebSessionIdResolverCE() { @Override public void setSessionId(ServerWebExchange exchange, String id) { - addCookieInitializer(); + addCookieInitializers(); super.setSessionId(exchange, id); } - protected void addCookieInitializer() { + protected void addCookieInitializers() { // Add the appropriate SameSite attribute based on the exchange attribute addCookieInitializer((builder) -> builder.sameSite(LAX).secure(true)); }