fix: Logout user, if session deserialization fails (#19188)

We handle this in the global error handler, looking for the error
message that indicates this cause, and include a cookie deletion header,
so the user can recover by logging in again.

Signed-off-by: Shrikant Sharat Kandula <shrikant@appsmith.com>
This commit is contained in:
Shrikant Sharat Kandula 2022-12-25 11:31:51 +05:30 committed by GitHub
parent 9ba6fab85d
commit e58cdf40bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -12,6 +12,7 @@ import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseCookie;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
@ -31,6 +32,10 @@ import static org.springframework.web.reactive.function.server.RouterFunctions.r
@Component
@Order(-2)
public class AppSmithErrorWebExceptionHandler extends DefaultErrorWebExceptionHandler {
public static final String DESERIALIZATION_ERROR_MESSAGE =
"Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer";
@Autowired
public AppSmithErrorWebExceptionHandler(ErrorAttributes errorAttributes, WebProperties webProperties,
ServerProperties serverProperties, ApplicationContext applicationContext,
@ -52,9 +57,25 @@ public class AppSmithErrorWebExceptionHandler extends DefaultErrorWebExceptionHa
Map<String, Object> error = getErrorAttributes(request, ErrorAttributeOptions.of(ErrorAttributeOptions.Include.STACK_TRACE));
int errorCode = getHttpStatus(error);
return ServerResponse.status(errorCode).
contentType(MediaType.APPLICATION_JSON).
body(BodyInserters.
fromValue(new ResponseDTO<>(errorCode, new ErrorDTO(errorCode, String.valueOf(error.get("error"))))));
ServerResponse.BodyBuilder responseBuilder = ServerResponse.status(errorCode)
.contentType(MediaType.APPLICATION_JSON);
if (errorCode == 500 && String.valueOf(error.get("trace")).contains(DESERIALIZATION_ERROR_MESSAGE)) {
// If the error is regarding a deserialization error in the session data, then the user is essentially locked out.
// They have to use a different browser, or Incognito, or clear their cookies to get back in. So, we'll delete
// the SESSION cookie here, so that the user gets sent back to the Login page, and they can unblock themselves.
responseBuilder = responseBuilder.cookie(
ResponseCookie.from("SESSION", "")
.httpOnly(true)
.path("/")
.maxAge(0)
.build()
);
}
return responseBuilder.body(
BodyInserters
.fromValue(new ResponseDTO<>(errorCode, new ErrorDTO(errorCode, String.valueOf(error.get("error")))))
);
}
}