From 647b54f205025be7e7469b16dacdb50d3b82902b Mon Sep 17 00:00:00 2001 From: zlt Date: Mon, 30 Mar 2020 10:54:57 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=84=E8=8C=83=E5=BC=82=E5=B8=B8=E8=BF=94?= =?UTF-8?q?=E5=9B=9Ejson?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/DefaultSecurityHandlerConfig.java | 5 +- .../java/com/central/common/model/Result.java | 17 ++-- .../central/common/utils/ResponseUtil.java | 23 ++++- .../gateway/auth/JsonAccessDeniedHandler.java | 2 +- .../auth/JsonAuthenticationEntryPoint.java | 2 +- .../CustomErrorWebFluxAutoConfiguration.java | 75 ++++++++++++++++ .../error/JsonErrorWebExceptionHandler.java | 88 +++++++++++++++++++ .../oauth/filter/OauthTokenAspect.java | 2 +- 8 files changed, 194 insertions(+), 20 deletions(-) create mode 100644 zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/CustomErrorWebFluxAutoConfiguration.java create mode 100644 zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/JsonErrorWebExceptionHandler.java diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/config/DefaultSecurityHandlerConfig.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/config/DefaultSecurityHandlerConfig.java index 37c3136..bd99043 100644 --- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/config/DefaultSecurityHandlerConfig.java +++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/config/DefaultSecurityHandlerConfig.java @@ -4,7 +4,6 @@ import com.central.common.utils.ResponseUtil; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; -import org.springframework.http.HttpStatus; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler; @@ -30,7 +29,7 @@ public class DefaultSecurityHandlerConfig { */ @Bean public AuthenticationEntryPoint authenticationEntryPoint() { - return (request, response, authException) -> ResponseUtil.responseWriter(objectMapper, response, authException.getMessage(), HttpStatus.UNAUTHORIZED.value()); + return (request, response, authException) -> ResponseUtil.responseFailed(objectMapper, response, authException.getMessage()); } @Bean @@ -49,7 +48,7 @@ public class DefaultSecurityHandlerConfig { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException authException) throws IOException, ServletException { - ResponseUtil.responseWriter(objectMapper, response, authException.getMessage(), HttpStatus.FORBIDDEN.value()); + ResponseUtil.responseFailed(objectMapper, response, authException.getMessage()); } }; } diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/Result.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/Result.java index e6ae591..13682bd 100644 --- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/Result.java +++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/model/Result.java @@ -19,31 +19,26 @@ public class Result implements Serializable { private String resp_msg; public static Result succeed(String msg) { - return succeedWith(null, CodeEnum.SUCCESS.getCode(), msg); + return of(null, CodeEnum.SUCCESS.getCode(), msg); } public static Result succeed(T model, String msg) { - return succeedWith(model, CodeEnum.SUCCESS.getCode(), msg); + return of(model, CodeEnum.SUCCESS.getCode(), msg); } public static Result succeed(T model) { - return succeedWith(model, CodeEnum.SUCCESS.getCode(), ""); + return of(model, CodeEnum.SUCCESS.getCode(), ""); } - public static Result succeedWith(T datas, Integer code, String msg) { + public static Result of(T datas, Integer code, String msg) { return new Result<>(datas, code, msg); } public static Result failed(String msg) { - return failedWith(null, CodeEnum.ERROR.getCode(), msg); + return of(null, CodeEnum.ERROR.getCode(), msg); } public static Result failed(T model, String msg) { - return failedWith(model, CodeEnum.ERROR.getCode(), msg); + return of(model, CodeEnum.ERROR.getCode(), msg); } - - public static Result failedWith(T datas, Integer code, String msg) { - return new Result<>(datas, code, msg); - } - } diff --git a/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/ResponseUtil.java b/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/ResponseUtil.java index 6a40bb8..f489366 100644 --- a/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/ResponseUtil.java +++ b/zlt-commons/zlt-common-core/src/main/java/com/central/common/utils/ResponseUtil.java @@ -35,7 +35,7 @@ public class ResponseUtil { * @throws IOException */ public static void responseWriter(ObjectMapper objectMapper, HttpServletResponse response, String msg, int httpStatus) throws IOException { - Result result = Result.succeedWith(null, httpStatus, msg); + Result result = Result.of(null, httpStatus, msg); responseWrite(objectMapper, response, result); } @@ -76,11 +76,28 @@ public class ResponseUtil { * webflux的response返回json对象 */ public static Mono responseWriter(ServerWebExchange exchange, int httpStatus, String msg) { - Result result = Result.succeedWith(null, httpStatus, msg); + Result result = Result.of(null, httpStatus, msg); + return responseWrite(exchange, httpStatus, result); + } + + public static Mono responseFailed(ServerWebExchange exchange, String msg) { + Result result = Result.failed(msg); + return responseWrite(exchange, HttpStatus.INTERNAL_SERVER_ERROR.value(), result); + } + + public static Mono responseFailed(ServerWebExchange exchange, int httpStatus, String msg) { + Result result = Result.failed(msg); + return responseWrite(exchange, httpStatus, result); + } + + public static Mono responseWrite(ServerWebExchange exchange, int httpStatus, Result result) { + if (httpStatus == 0) { + httpStatus = HttpStatus.INTERNAL_SERVER_ERROR.value(); + } ServerHttpResponse response = exchange.getResponse(); response.getHeaders().setAccessControlAllowCredentials(true); response.getHeaders().setAccessControlAllowOrigin("*"); - response.setStatusCode(HttpStatus.valueOf(result.getResp_code())); + response.setStatusCode(HttpStatus.valueOf(httpStatus)); response.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8); DataBufferFactory dataBufferFactory = response.bufferFactory(); DataBuffer buffer = dataBufferFactory.wrap(JSONObject.toJSONString(result).getBytes(Charset.defaultCharset())); diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAccessDeniedHandler.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAccessDeniedHandler.java index c2ba9ce..34076c8 100644 --- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAccessDeniedHandler.java +++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAccessDeniedHandler.java @@ -21,6 +21,6 @@ import reactor.core.publisher.Mono; public class JsonAccessDeniedHandler implements ServerAccessDeniedHandler { @Override public Mono handle(ServerWebExchange exchange, AccessDeniedException e) { - return ResponseUtil.responseWriter(exchange, HttpStatus.FORBIDDEN.value(), e.getMessage()); + return ResponseUtil.responseFailed(exchange, HttpStatus.FORBIDDEN.value(), e.getMessage()); } } diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAuthenticationEntryPoint.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAuthenticationEntryPoint.java index 05fac97..672580a 100644 --- a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAuthenticationEntryPoint.java +++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/auth/JsonAuthenticationEntryPoint.java @@ -21,6 +21,6 @@ import reactor.core.publisher.Mono; public class JsonAuthenticationEntryPoint implements ServerAuthenticationEntryPoint { @Override public Mono commence(ServerWebExchange exchange, AuthenticationException e) { - return ResponseUtil.responseWriter(exchange, HttpStatus.UNAUTHORIZED.value(), e.getMessage()); + return ResponseUtil.responseFailed(exchange, HttpStatus.UNAUTHORIZED.value(), e.getMessage()); } } diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/CustomErrorWebFluxAutoConfiguration.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/CustomErrorWebFluxAutoConfiguration.java new file mode 100644 index 0000000..d9f0b73 --- /dev/null +++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/CustomErrorWebFluxAutoConfiguration.java @@ -0,0 +1,75 @@ +package com.central.gateway.error; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.web.ResourceProperties; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.codec.ServerCodecConfigurer; +import org.springframework.web.reactive.config.WebFluxConfigurer; +import org.springframework.web.reactive.result.view.ViewResolver; + +import java.util.Collections; +import java.util.List; + +/** + * 自定义异常处理 + * + * @author zlt + * @date 2020/3/30 + *

+ * Blog: https://blog.csdn.net/zlt2000 + * Github: https://github.com/zlt2000 + */ +@Configuration +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +@ConditionalOnClass(WebFluxConfigurer.class) +@AutoConfigureBefore(WebFluxAutoConfiguration.class) +@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class}) +public class CustomErrorWebFluxAutoConfiguration { + private final ServerProperties serverProperties; + + private final ApplicationContext applicationContext; + + private final ResourceProperties resourceProperties; + + private final List viewResolvers; + + private final ServerCodecConfigurer serverCodecConfigurer; + + public CustomErrorWebFluxAutoConfiguration(ServerProperties serverProperties, + ResourceProperties resourceProperties, + ObjectProvider> viewResolversProvider, + ServerCodecConfigurer serverCodecConfigurer, + ApplicationContext applicationContext) { + this.serverProperties = serverProperties; + this.applicationContext = applicationContext; + this.resourceProperties = resourceProperties; + this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList); + this.serverCodecConfigurer = serverCodecConfigurer; + } + + @Bean + @Order(Ordered.HIGHEST_PRECEDENCE) + public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) { + JsonErrorWebExceptionHandler exceptionHandler = new JsonErrorWebExceptionHandler( + errorAttributes, + this.resourceProperties, + this.serverProperties.getError(), + this.applicationContext); + exceptionHandler.setViewResolvers(this.viewResolvers); + exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters()); + exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders()); + return exceptionHandler; + } +} diff --git a/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/JsonErrorWebExceptionHandler.java b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/JsonErrorWebExceptionHandler.java new file mode 100644 index 0000000..3bb1533 --- /dev/null +++ b/zlt-gateway/sc-gateway/src/main/java/com/central/gateway/error/JsonErrorWebExceptionHandler.java @@ -0,0 +1,88 @@ +package com.central.gateway.error; + +import org.springframework.boot.autoconfigure.web.ErrorProperties; +import org.springframework.boot.autoconfigure.web.ResourceProperties; +import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler; +import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.context.ApplicationContext; +import org.springframework.http.HttpStatus; +import org.springframework.web.reactive.function.server.*; + +import java.util.HashMap; +import java.util.Map; + +/** + * 自定义异常处理 + * + * @author zlt + * @date 2020/3/30 + *

+ * Blog: https://blog.csdn.net/zlt2000 + * Github: https://github.com/zlt2000 + */ +public class JsonErrorWebExceptionHandler extends DefaultErrorWebExceptionHandler { + public JsonErrorWebExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties, + ErrorProperties errorProperties, ApplicationContext applicationContext) { + super(errorAttributes, resourceProperties, errorProperties, applicationContext); + } + + /** + * 获取异常属性 + */ + @Override + protected Map getErrorAttributes(ServerRequest request, boolean includeStackTrace) { + Throwable error = super.getError(request); + return responseError(this.buildMessage(request, error)); + } + + /** + * 指定响应处理方法为JSON处理的方法 + * @param errorAttributes + */ + @Override + protected RouterFunction getRoutingFunction(ErrorAttributes errorAttributes) { + return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse); + } + + /** + * 根据code获取对应的HttpStatus + * @param errorAttributes + */ + @Override + protected HttpStatus getHttpStatus(Map errorAttributes) { + int statusCode = (int) errorAttributes.get("code"); + return HttpStatus.valueOf(statusCode); + } + + /** + * 构建异常信息 + * @param request + * @param ex + * @return + */ + private String buildMessage(ServerRequest request, Throwable ex) { + StringBuilder message = new StringBuilder("Failed to handle request ["); + message.append(request.methodName()); + message.append(" "); + message.append(request.uri()); + message.append("]"); + if (ex != null) { + message.append(": "); + message.append(ex.getMessage()); + } + return message.toString(); + } + + /** + * 构建返回的JSON数据格式 + * @param errorMessage 异常信息 + * @return + */ + public static Map responseError(String errorMessage) { + Map map = new HashMap<>(); + map.put("resp_code", 1); + map.put("resp_msg", errorMessage); + map.put("datas", null); + return map; + } +} diff --git a/zlt-uaa/src/main/java/com/central/oauth/filter/OauthTokenAspect.java b/zlt-uaa/src/main/java/com/central/oauth/filter/OauthTokenAspect.java index 3d587f1..e20b8f8 100644 --- a/zlt-uaa/src/main/java/com/central/oauth/filter/OauthTokenAspect.java +++ b/zlt-uaa/src/main/java/com/central/oauth/filter/OauthTokenAspect.java @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; -import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.InsufficientAuthenticationException; @@ -65,6 +64,7 @@ public class OauthTokenAspect { .body(Result.succeed(body)); } } catch (Exception e) { + log.error("授权错误", e); return ResponseEntity .status(HttpStatus.BAD_REQUEST) .body(Result.failed(e.getMessage())); -- GitLab