From 77d6d34b60a73e523619b740d0c07f5291e5accb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johnny=20Miller=20=28=E9=94=BA=E4=BF=8A=29?= Date: Mon, 28 Dec 2020 16:53:41 +0800 Subject: [PATCH] perf($Gateway): capture SecurityException --- .../JwtReactiveServerSecurityContextRepository.java | 6 ++++-- .../universal/handler/GlobalExceptionHandler.java | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/api-gateway/src/main/java/com/jmsoftware/maf/apigateway/security/JwtReactiveServerSecurityContextRepository.java b/api-gateway/src/main/java/com/jmsoftware/maf/apigateway/security/JwtReactiveServerSecurityContextRepository.java index e5c64cfe..921b9484 100644 --- a/api-gateway/src/main/java/com/jmsoftware/maf/apigateway/security/JwtReactiveServerSecurityContextRepository.java +++ b/api-gateway/src/main/java/com/jmsoftware/maf/apigateway/security/JwtReactiveServerSecurityContextRepository.java @@ -2,11 +2,13 @@ import cn.hutool.core.util.StrUtil; import com.jmsoftware.maf.apigateway.security.configuration.JwtConfiguration; +import com.jmsoftware.maf.common.exception.SecurityException; import com.jmsoftware.maf.reactivespringbootstarter.configuration.MafConfiguration; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import lombok.val; import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; import org.springframework.security.authentication.ReactiveAuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContext; @@ -48,7 +50,7 @@ public Mono load(ServerWebExchange exchange) { if (StrUtil.isBlank(authorization) || !authorization.startsWith(JwtConfiguration.TOKEN_PREFIX)) { log.warn("Pre-authentication failure! Cause: `{}` in HTTP headers not found. Request URL: [{}] {}", HttpHeaders.AUTHORIZATION, request.getMethod(), request.getURI()); - return Mono.empty(); + return Mono.error(new SecurityException(HttpStatus.FORBIDDEN, "Invalid HTTP headers")); } val jwt = authorization.replace(JwtConfiguration.TOKEN_PREFIX, ""); String username; @@ -57,7 +59,7 @@ public Mono load(ServerWebExchange exchange) { } catch (Exception e) { log.warn("Pre-authentication failure! Cause: Exception occurred when parsing JWT. {}. Request URL: [{}] {}", e.getMessage(), request.getMethod(), request.getURI()); - return Mono.empty(); + return Mono.error(new SecurityException(HttpStatus.FORBIDDEN, e.getMessage())); } val userPrincipal = UserPrincipal.createByUsername(username); log.info("User principal is created. {}", userPrincipal); diff --git a/api-gateway/src/main/java/com/jmsoftware/maf/apigateway/universal/handler/GlobalExceptionHandler.java b/api-gateway/src/main/java/com/jmsoftware/maf/apigateway/universal/handler/GlobalExceptionHandler.java index bcfaf51e..f6008760 100644 --- a/api-gateway/src/main/java/com/jmsoftware/maf/apigateway/universal/handler/GlobalExceptionHandler.java +++ b/api-gateway/src/main/java/com/jmsoftware/maf/apigateway/universal/handler/GlobalExceptionHandler.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.jmsoftware.maf.common.bean.ResponseBodyBean; +import com.jmsoftware.maf.common.exception.SecurityException; import com.jmsoftware.maf.reactivespringbootstarter.util.RequestUtil; import com.netflix.hystrix.exception.HystrixRuntimeException; import lombok.RequiredArgsConstructor; @@ -75,6 +76,10 @@ private ResponseBodyBean setResponseBody(ServerHttpResponse response, Throwab response.setStatusCode(HttpStatus.SERVICE_UNAVAILABLE); return ResponseBodyBean.ofStatus(HttpStatus.SERVICE_UNAVAILABLE, String.format("%s %s", ex.getMessage(), ex.getCause().getMessage())); + } else if (ex instanceof SecurityException) { + HttpStatus status = HttpStatus.valueOf(((SecurityException) ex).getCode()); + response.setStatusCode(status); + return ResponseBodyBean.ofStatus(status, ex.getMessage()); } response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR); return ResponseBodyBean.ofStatus(HttpStatus.INTERNAL_SERVER_ERROR,