Error handling in JwtAuthenticationFilter
This commit is contained in:
parent
f6f3289fed
commit
ac2f0c1d6d
@ -4,6 +4,6 @@ import lombok.Data;
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class LoginRQB {
|
public class LoginRQB {
|
||||||
private final String login;
|
private String login;
|
||||||
private final String password;
|
private String password;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import lombok.Getter;
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class ErrorResponse {
|
public class ErrorResponsePayload {
|
||||||
private int status;
|
private int status;
|
||||||
private String error;
|
private String error;
|
||||||
private String message;
|
private String message;
|
@ -18,54 +18,54 @@ import org.springframework.web.servlet.resource.NoResourceFoundException;
|
|||||||
|
|
||||||
@RestControllerAdvice
|
@RestControllerAdvice
|
||||||
public class GlobalExceptionHandler {
|
public class GlobalExceptionHandler {
|
||||||
public static ResponseEntity<ErrorResponse> buildErrorResponse(Exception e, HttpStatus status, @Nullable String message) {
|
public static ResponseEntity<ErrorResponsePayload> buildErrorResponse(Exception e, HttpStatus status, @Nullable String message) {
|
||||||
ErrorResponse errorResponse = new ErrorResponse(
|
ErrorResponsePayload errorResponsePayload = new ErrorResponsePayload(
|
||||||
status.value(),
|
status.value(),
|
||||||
status.getReasonPhrase(),
|
status.getReasonPhrase(),
|
||||||
message == null ? e.getMessage() : message
|
message == null ? e.getMessage() : message
|
||||||
);
|
);
|
||||||
return new ResponseEntity<>(errorResponse, status);
|
return new ResponseEntity<>(errorResponsePayload, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(Exception.class)
|
@ExceptionHandler(Exception.class)
|
||||||
public ResponseEntity<ErrorResponse> handleException(Exception e, WebRequest request) {
|
public ResponseEntity<ErrorResponsePayload> handleException(Exception e, WebRequest request) {
|
||||||
Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
||||||
logger.error("Unexpected error occurred", e);
|
logger.error("Unexpected error occurred", e);
|
||||||
return buildErrorResponse(e, HttpStatus.INTERNAL_SERVER_ERROR, "Unexpected error occurred");
|
return buildErrorResponse(e, HttpStatus.INTERNAL_SERVER_ERROR, "Unexpected error occurred");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(BadRequestHTTPException.class)
|
@ExceptionHandler(BadRequestHTTPException.class)
|
||||||
public ResponseEntity<ErrorResponse> handleBadBadRequestHTTPException(BadRequestHTTPException e, WebRequest request) {
|
public ResponseEntity<ErrorResponsePayload> handleBadBadRequestHTTPException(BadRequestHTTPException e, WebRequest request) {
|
||||||
return buildErrorResponse(e, HttpStatus.BAD_REQUEST, null);
|
return buildErrorResponse(e, HttpStatus.BAD_REQUEST, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(NotFoundHTTPException.class)
|
@ExceptionHandler(NotFoundHTTPException.class)
|
||||||
public ResponseEntity<ErrorResponse> handleNotFoundHTTPException(NotFoundHTTPException e, WebRequest request) {
|
public ResponseEntity<ErrorResponsePayload> handleNotFoundHTTPException(NotFoundHTTPException e, WebRequest request) {
|
||||||
return buildErrorResponse(e, HttpStatus.NOT_FOUND, null);
|
return buildErrorResponse(e, HttpStatus.NOT_FOUND, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(AlreadyExistsHTTPException.class)
|
@ExceptionHandler(AlreadyExistsHTTPException.class)
|
||||||
public ResponseEntity<ErrorResponse> handleAlreadyExistsHTTPException(AlreadyExistsHTTPException e, WebRequest request) {
|
public ResponseEntity<ErrorResponsePayload> handleAlreadyExistsHTTPException(AlreadyExistsHTTPException e, WebRequest request) {
|
||||||
return buildErrorResponse(e, HttpStatus.CONFLICT, null);
|
return buildErrorResponse(e, HttpStatus.CONFLICT, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(HttpMessageNotReadableException.class)
|
@ExceptionHandler(HttpMessageNotReadableException.class)
|
||||||
public ResponseEntity<ErrorResponse> handleHttpMessageNotReadableException(InvalidFormatException e, WebRequest request) {
|
public ResponseEntity<ErrorResponsePayload> handleHttpMessageNotReadableException(InvalidFormatException e, WebRequest request) {
|
||||||
return buildErrorResponse(e, HttpStatus.BAD_REQUEST, "Bad request payload format: failed to parse");
|
return buildErrorResponse(e, HttpStatus.BAD_REQUEST, "Bad request payload format: failed to parse");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
|
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
|
||||||
public ResponseEntity<ErrorResponse> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e, WebRequest request) {
|
public ResponseEntity<ErrorResponsePayload> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e, WebRequest request) {
|
||||||
return buildErrorResponse(e, HttpStatus.METHOD_NOT_ALLOWED, null);
|
return buildErrorResponse(e, HttpStatus.METHOD_NOT_ALLOWED, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(UnauthorizedHTTPException.class)
|
@ExceptionHandler(UnauthorizedHTTPException.class)
|
||||||
public ResponseEntity<ErrorResponse> handleUnauthorizedHTTPException(UnauthorizedHTTPException e, WebRequest request) {
|
public ResponseEntity<ErrorResponsePayload> handleUnauthorizedHTTPException(UnauthorizedHTTPException e, WebRequest request) {
|
||||||
return buildErrorResponse(e, HttpStatus.UNAUTHORIZED, null);
|
return buildErrorResponse(e, HttpStatus.UNAUTHORIZED, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(InternalAuthenticationServiceException.class)
|
@ExceptionHandler(InternalAuthenticationServiceException.class)
|
||||||
public ResponseEntity<ErrorResponse> handleInternalAuthenticationServiceException(InternalAuthenticationServiceException e, WebRequest request) {
|
public ResponseEntity<ErrorResponsePayload> handleInternalAuthenticationServiceException(InternalAuthenticationServiceException e, WebRequest request) {
|
||||||
Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
||||||
logger.error("Unexpected error occurred", e);
|
logger.error("Unexpected error occurred", e);
|
||||||
|
|
||||||
@ -73,12 +73,12 @@ public class GlobalExceptionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(NoResourceFoundException.class)
|
@ExceptionHandler(NoResourceFoundException.class)
|
||||||
public ResponseEntity<ErrorResponse> handleNoResourceFoundException(NoResourceFoundException e, WebRequest request) {
|
public ResponseEntity<ErrorResponsePayload> handleNoResourceFoundException(NoResourceFoundException e, WebRequest request) {
|
||||||
return buildErrorResponse(e, HttpStatus.NOT_FOUND, null);
|
return buildErrorResponse(e, HttpStatus.NOT_FOUND, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(ForbiddenHTTPException.class)
|
@ExceptionHandler(ForbiddenHTTPException.class)
|
||||||
public ResponseEntity<ErrorResponse> handleForbiddenHTTPException(ForbiddenHTTPException e, WebRequest request) {
|
public ResponseEntity<ErrorResponsePayload> handleForbiddenHTTPException(ForbiddenHTTPException e, WebRequest request) {
|
||||||
return buildErrorResponse(e, HttpStatus.FORBIDDEN, null);
|
return buildErrorResponse(e, HttpStatus.FORBIDDEN, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
package com.displaynone.acss.security;
|
package com.displaynone.acss.security;
|
||||||
|
|
||||||
import com.displaynone.acss.components.auth.AuthComponent;
|
import com.displaynone.acss.components.auth.AuthComponent;
|
||||||
import com.displaynone.acss.exception.ErrorResponse;
|
import com.displaynone.acss.exception.ErrorResponsePayload;
|
||||||
import com.displaynone.acss.exception.generics.NotFoundHTTPException;
|
import com.displaynone.acss.exception.generics.NotFoundHTTPException;
|
||||||
import com.displaynone.acss.exception.generics.UnauthorizedHTTPException;
|
import com.displaynone.acss.exception.generics.UnauthorizedHTTPException;
|
||||||
import com.displaynone.acss.exception.handler.GlobalExceptionHandler;
|
import com.displaynone.acss.utils.GlobalUtils;
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
@ -44,12 +43,13 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
UsernamePasswordAuthenticationToken authentication;
|
UsernamePasswordAuthenticationToken authentication;
|
||||||
try {
|
try {
|
||||||
authentication = authComponent.authenticateByAccessToken(jwt);
|
authentication = authComponent.authenticateByAccessToken(jwt);
|
||||||
} catch (NotFoundHTTPException e) {
|
} catch (NotFoundHTTPException | UnauthorizedHTTPException e) {
|
||||||
ResponseEntity<ErrorResponse> responseEntity = GlobalExceptionHandler.buildErrorResponse(new UnauthorizedHTTPException(e.getMessage()), HttpStatus.UNAUTHORIZED, null);
|
GlobalUtils.writeErrorToResponse(new ErrorResponsePayload(
|
||||||
return; // TODO
|
HttpStatus.UNAUTHORIZED.value(),
|
||||||
} catch (UnauthorizedHTTPException e) {
|
HttpStatus.UNAUTHORIZED.getReasonPhrase(),
|
||||||
ResponseEntity<ErrorResponse> responseEntity = GlobalExceptionHandler.buildErrorResponse(new UnauthorizedHTTPException(e.getMessage()), HttpStatus.UNAUTHORIZED, null);
|
e.getMessage()
|
||||||
return; // TODO
|
), response);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
package com.displaynone.acss.utils;
|
package com.displaynone.acss.utils;
|
||||||
|
|
||||||
|
import com.displaynone.acss.exception.ErrorResponsePayload;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -11,6 +17,8 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class GlobalUtils {
|
public class GlobalUtils {
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
public boolean hasAnyNullField(Object obj, @Nullable List<String> fieldsToIgnore) {
|
public boolean hasAnyNullField(Object obj, @Nullable List<String> fieldsToIgnore) {
|
||||||
return Arrays.stream(obj.getClass().getDeclaredFields())
|
return Arrays.stream(obj.getClass().getDeclaredFields())
|
||||||
.filter(field -> fieldsToIgnore == null || !fieldsToIgnore.contains(field.getName()))
|
.filter(field -> fieldsToIgnore == null || !fieldsToIgnore.contains(field.getName()))
|
||||||
@ -31,4 +39,11 @@ public class GlobalUtils {
|
|||||||
public <EntityT, DtoT> List<DtoT> convertAllToDTO(Collection<EntityT> entities, EntityMapper<EntityT, DtoT> mapper) {
|
public <EntityT, DtoT> List<DtoT> convertAllToDTO(Collection<EntityT> entities, EntityMapper<EntityT, DtoT> mapper) {
|
||||||
return entities.stream().map(mapper::convertToDTO).collect(Collectors.toList());
|
return entities.stream().map(mapper::convertToDTO).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeErrorToResponse(ErrorResponsePayload payload, HttpServletResponse response) throws IOException {
|
||||||
|
String jsonResponse = objectMapper.writeValueAsString(payload);
|
||||||
|
response.setStatus(payload.getStatus());
|
||||||
|
response.setContentType("application/json");
|
||||||
|
response.getWriter().write(jsonResponse);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user