
1
@SuppressWarnings("rawtypes")@Component@Slf4jpublic class ApiAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<ApiAuthGatewayFilterFactory.Config> {private static final String USER_HEADER_NAME = "User-Info";@Autowiredprivate UserClient userClient;public ApiAuthGatewayFilterFactory() {super(Config.class);}@Overridepublic List<String> shortcutFieldOrder() {return Collections.singletonList("checkAuth");}@Overridepublic GatewayFilter apply(Config config) {return (exchange, chain) -> {if (config.checkAuth) {String cookie = exchange.getRequest().getHeaders().getFirst("Cookie");String url = exchange.getRequest().getPath().toString();String httpMethod = exchange.getRequest().getMethodValue();// 这里调用了feign接口,到用户模块进行鉴权ResultResponse resultResponse = userClient.checkPermission(url, httpMethod, cookie);if (resultResponse.isSuccess()) {// 鉴权通过,则将用户信息放入header中,传到下游服务ServerHttpRequest request = exchange.getRequest().mutate().header(USER_HEADER_NAME, JSON.toJSONString(resultResponse.getData())).build();return chain.filter(exchange.mutate().request(request).build());} else {return Mono.defer(() -> {exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);final ServerHttpResponse response = exchange.getResponse();byte[] bytes = JSON.toJSONString(resultResponse).getBytes(StandardCharsets.UTF_8);DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);return response.writeWith(Flux.just(buffer));});}} else {return chain.filter(exchange);}};}@NoArgsConstructor@Getter@Setter@ToStringpublic static class Config {private boolean checkAuth;}}
java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-3at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:83)Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:Error has been observed at the following site(s):|_ checkpoint ⇢ org.springframework.web.cors.reactive.CorsWebFilter [DefaultWebFilterChain]|_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]|_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]|_ checkpoint ⇢ HTTP GET "/api/v1/users/getUserInfo" [ExceptionHandlingWebHandler]
2
// 将feign调用封装成异步任务,通过线程池的方式提交Future<?> future = executorService.submit(() -> {userClient.checkPermission(url, httpMethod, cookie);});try {// 通过future方式获取结果ResultResponse resultResponse = (ResultResponse) future.get();if (resultResponse.isSuccess()) {ServerHttpRequest request = exchange.getRequest().mutate().header(USER_HEADER_NAME, JSON.toJSONString(resultResponse.getData())).build();return chain.filter(exchange.mutate().request(request).build());} else {return Mono.defer(() -> {exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);final ServerHttpResponse response = exchange.getResponse();byte[] bytes = JSON.toJSONString(resultResponse).getBytes(StandardCharsets.UTF_8);DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);return response.writeWith(Flux.just(buffer));});}} catch (InterruptedException | ExecutionException e) {// ignore exception}// 异常返回return Mono.defer(() -> {exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);final ServerHttpResponse response = exchange.getResponse();byte[] bytes = JSON.toJSONString("ERROR").getBytes(StandardCharsets.UTF_8);DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);return response.writeWith(Flux.just(buffer));});
4jpublic class ApiAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<ApiAuthGatewayFilterFactory.Config> {private static final String USER_HEADER_NAME = "User-Info";private UserReactiveClient userReactiveClient;public ApiAuthGatewayFilterFactory() {super(Config.class);}public List<String> shortcutFieldOrder() {return Collections.singletonList("checkAuth");}public GatewayFilter apply(Config config) {return (exchange, chain) -> {if (config.checkAuth) {String cookie = exchange.getRequest().getHeaders().getFirst("Cookie");String url = exchange.getRequest().getPath().toString();String httpMethod = exchange.getRequest().getMethodValue();// ReactiveFeign异步调用,获取鉴权结果return userReactiveClient.checkPermission(url, httpMethod, cookie).flatMap(commonResponse -> {// 鉴权不通过则返回异常if (!commonResponse.isSuccess()) {return Mono.defer(() -> {exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);final ServerHttpResponse response = exchange.getResponse();byte[] bytes = JSON.toJSONString(commonResponse).getBytes(StandardCharsets.UTF_8);DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);return response.writeWith(Flux.just(buffer));});} else {// 鉴权通过将用户信息带入后端log.info("User-Info: [{}]", JSON.toJSONString(commonResponse.getData()));ServerHttpRequest request = exchange.getRequest().mutate().header(USER_HEADER_NAME, JSON.toJSONString(commonResponse.getData())).build();return chain.filter(exchange.mutate().request(request).build());}});} else {return chain.filter(exchange);}};}public static class Config {private boolean checkAuth;}}
聊技术,不止于技术。
原文作者:WU双;如有侵权,请联系管理员删除。