欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

SpringCloud Gateway API 接口安全设计(加密、签名、安全) (I)

最编程 2024-04-20 15:24:10
...
public abstract class AbstractExceptionHandler { protected JSONObject buildErrorMap(Throwable ex) { JSONObject json = new JSONObject(); if (ex instanceof RSAException || ex instanceof IllegalArgumentException) { json.put("code", HttpStatus.BAD_REQUEST.value()); if (StringUtils.isNotBlank(ex.getMessage())){ json.put("msg", ex.getMessage()); }else { json.put("msg", "无效的请求"); } } else { json.put("code", HttpStatus.BAD_REQUEST.value()); json.put("msg", "未知错误联系管理员"); } return json; } } @Configuration public class GatewayExceptionConfig { @Primary @Bean @Order(Ordered.HIGHEST_PRECEDENCE) public ErrorWebExceptionHandler errorWebExceptionHandler(ObjectProvider<List<ViewResolver>> viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer) { GatewayExceptionHandler gatewayExceptionHandler = new GatewayExceptionHandler(); gatewayExceptionHandler.setViewResolvers(viewResolversProvider.getIfAvailable(Collections::emptyList)); gatewayExceptionHandler.setMessageWriters(serverCodecConfigurer.getWriters()); gatewayExceptionHandler.setMessageReaders(serverCodecConfigurer.getReaders()); return gatewayExceptionHandler; } } package com.demo.gateway.exception; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.codec.HttpMessageReader; import org.springframework.http.codec.HttpMessageWriter; import org.springframework.util.Assert; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.server.RequestPredicates; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.result.view.ViewResolver; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import java.util.Collections; import java.util.List; import java.util.Map; @Slf4j public class GatewayExceptionHandler extends AbstractExceptionHandler implements ErrorWebExceptionHandler { private List<HttpMessageReader<?>> messageReaders = Collections.emptyList(); private List<HttpMessageWriter<?>> messageWriters = Collections.emptyList(); private List<ViewResolver> viewResolvers = Collections.emptyList(); private ThreadLocal<JSONObject> exceptionHandlerResult = new ThreadLocal<>(); public void setMessageReaders(List<HttpMessageReader<?>> messageReaders) { Assert.notNull(messageReaders, "'messageReaders' must not be null"); this.messageReaders = messageReaders; } public void setViewResolvers(List<ViewResolver> viewResolvers) { this.viewResolvers = viewResolvers; } public void setMessageWriters(List<HttpMessageWriter<?>> messageWriters) { Assert.notNull(messageWriters, "'messageWriters' must not be null"); this.messageWriters = messageWriters; } @Override public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) { JSONObject errorInfo = super.buildErrorMap(ex); if (exchange.getResponse().isCommitted()) { return Mono.error(ex); } exceptionHandlerResult.set(errorInfo); ServerRequest newRequest = ServerRequest.create(exchange, this.messageReaders); return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse).route(newRequest) .switchIfEmpty(Mono.error(ex)) .flatMap(handler -> handler.handle(newRequest)) .flatMap(response -> write(exchange, response)); } protected Mono<ServerResponse> renderErrorResponse(ServerRequest request) { Map<String, Object> result = exceptionHandlerResult.get(); return ServerResponse.status(HttpStatus.OK) .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromValue(result)); } private Mono<? extends Void> write(ServerWebExchange exchange, ServerResponse response) { exchange.getResponse().getHeaders().setContentType(response.headers().getContentType()); return response.writeTo(exchange, new ResponseContext()); } private class ResponseContext implements ServerResponse.Context { @Override public List<HttpMessageWriter<?>> messageWriters() { return GatewayExceptionHandler.this.messageWriters; } @Override public List<ViewResolver> viewResolvers() { return GatewayExceptionHandler.this.viewResolvers; } } }