Merge branch 'feature/auth-success-redirect' into 'release'

Redirect to the client's homepage on success of username password login

This has been done with the express purpose of ensuring that the session ID is set correctly in the browser by the client. This can only happen when there is a 302 redirect by the browser.

See merge request theappsmith/internal-tools-server!112
This commit is contained in:
Arpit Mohan 2019-12-12 09:46:38 +00:00
commit 9a1ed9a17c
3 changed files with 19 additions and 29 deletions

View File

@ -31,6 +31,7 @@ public enum AppsmithError {
GENERIC_BAD_REQUEST(401, 4019, "Bad Request: {0}"),
INVALID_PASSWORD_RESET(400, 4020, "Unable to reset the password. Please initiate a request via 'forgot password' link to reset your password"),
LOGIN_INTERNAL_ERROR(401, 4021, "Internal error while trying to login"),
INVALID_CREDENTIALS(200, 4022, "Invalid credentials provided. Did you input the credentials correctly?"),
INTERNAL_SERVER_ERROR(500, 5000, "Internal server error while processing request"),
REPOSITORY_SAVE_FAILED(500, 5001, "Repository save failed"),
PLUGIN_INSTALLATION_FAILED_DOWNLOAD_ERROR(500, 5002, "Due to error in downloading the plugin from remote repository, plugin installation has failed. Check the jar location and try again"),

View File

@ -28,15 +28,15 @@ public class FormAuthenticationFailureHandler implements ServerAuthenticationFai
@Override
public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) {
log.debug("In the form auth failure function");
log.error("In the login failure handler. Cause: {}", exception.getMessage());
ServerWebExchange exchange = webFilterExchange.getExchange();
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.setStatusCode(HttpStatus.valueOf(AppsmithError.INVALID_CREDENTIALS.getHttpErrorCode()));
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
ResponseDTO<Boolean> responseDTO = new ResponseDTO<>(HttpStatus.UNAUTHORIZED.value(),
new ErrorDTO(AppsmithError.UNAUTHORIZED_ACCESS.getHttpErrorCode(),
AppsmithError.UNAUTHORIZED_ACCESS.getMessage()));
ResponseDTO<Boolean> responseDTO = new ResponseDTO<>(AppsmithError.INVALID_CREDENTIALS.getHttpErrorCode(),
new ErrorDTO(AppsmithError.INVALID_CREDENTIALS.getAppErrorCode(),
AppsmithError.INVALID_CREDENTIALS.getMessage()));
String responseStr;
try {

View File

@ -1,51 +1,40 @@
package com.appsmith.server.filters;
import com.appsmith.server.dtos.ResponseDTO;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.DefaultServerRedirectStrategy;
import org.springframework.security.web.server.ServerRedirectStrategy;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.net.URI;
@Slf4j
@Component
@RequiredArgsConstructor
public class FormAuthenticationSuccessHandler implements ServerAuthenticationSuccessHandler {
private final ObjectMapper objectMapper;
private ServerRedirectStrategy redirectStrategy = new DefaultServerRedirectStrategy();
@Override
public Mono<Void> onAuthenticationSuccess(WebFilterExchange webFilterExchange,
Authentication authentication) {
log.debug("In the form auth success function");
log.debug("Login succeeded for user: {}", authentication.getPrincipal());
ServerWebExchange exchange = webFilterExchange.getExchange();
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.OK);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
ResponseDTO<Boolean> responseDTO = new ResponseDTO<>(HttpStatus.OK.value(), true, null);
String responseStr;
try {
responseStr = objectMapper.writeValueAsString(responseDTO);
} catch (JsonProcessingException e) {
log.error("IOException caught while serializing auth success response to string. Cause: ", e);
return response.writeWith(Mono.error(new AppsmithException(AppsmithError.LOGIN_INTERNAL_ERROR)));
// On authentication success, we send a redirect to the client's home page. This ensures that the session
// is set in the cookie on the browser.
String originHeader = exchange.getRequest().getHeaders().getOrigin();
if(originHeader == null || originHeader.isEmpty()) {
originHeader = "/";
}
DataBuffer buffer = response.bufferFactory().wrap(responseStr.getBytes());
return response.writeWith(Mono.just(buffer));
URI defaultRedirectLocation = URI.create(originHeader);
return this.redirectStrategy.sendRedirect(exchange, defaultRedirectLocation);
}
}