gpt4 book ai didi

java - 如何使用 Spring Cloud Gateway 自定义过滤器来过滤每个请求?

转载 作者:行者123 更新时间:2023-12-03 17:11:15 25 4
gpt4 key购买 nike

这是我第一次使用 Spring Cloud Gateway 实现。
我需要过滤每个请求并在某些路径上应用过滤器验证。关注 Baeldung Custom Filters tutorial我做了一个简单的应用程序来过滤请求。
应用程序必须释放类似 /actuator/health 的路径并验证后端服务的特定路径。到目前为止,我已经实现了一个 GlobalFilter和一个 GatewayFilterFactory .每个请求都会调用全局过滤器,但在应用程序启动时只调用一次 GatewayFilter,这样我就无法对每个请求进行身份验证。 auth 逻辑是关于特定的头字段。所以,我的颗粒化问题是:

  • 如何使用特定路径验证每个请求?
  • 如何拒绝请求并发送错误消息?

  • 全局过滤器
    @Component
    public class LoggingGlobalPreFilter implements GlobalFilter {

    final Logger LOGGER = LoggerFactory.getLogger(LoggingGlobalPreFilter.class);

    @Override
    public Mono<Void> filter(
    ServerWebExchange exchange,
    GatewayFilterChain chain) {
    LOGGER.info("Global Pre Filter executed");
    return chain.filter(exchange);
    }

    }
    网关过滤器
    @Component
    public class LoggingGatewayFilterFactory extends
    AbstractGatewayFilterFactory<LoggingGatewayFilterFactory.Config> {

    final Logger LOGGER =
    LoggerFactory.getLogger(LoggingGatewayFilterFactory.class);

    public LoggingGatewayFilterFactory() {
    super(Config.class);
    }

    private Mono<Void> onError(ServerWebExchange exchange, String err, HttpStatus httpStatus) {
    ServerHttpResponse response = exchange.getResponse();
    response.setStatusCode(httpStatus);
    return response.setComplete();
    }

    private boolean isAuthorizationValid(String authorizationHeader) {
    boolean isValid = true;
    return authorizationHeader.equals("x-header");
    }

    @Override
    public GatewayFilter apply(Config config) {
    LOGGER.info("M=apply, Msg=Applying Gateway Filter....");
    return ((exchange, chain) -> {
    LOGGER.info("M=apply, Msg=Applying Gateway Filter...."); // APARENTELLY NEVER ENTER HERE.
    ServerHttpRequest request = exchange.getRequest();

    if (!request.getHeaders().containsKey(TsApiGatewayConstants.HEADER_APIKEY)) {
    return this.onError(exchange, TsApiGatewayConstants.MESSAGE_API_KEY_MISSING, HttpStatus.UNAUTHORIZED);
    }

    String apiKey = request.getHeaders().get(TsApiGatewayConstants.HEADER_APIKEY).get(0);
    String userAgent = request.getHeaders().get(TsApiGatewayConstants.HEADER_USER_AGENT).get(0);

    if (!this.isAuthorizationValid(userAgent)) {
    return this.onError(exchange, TsApiGatewayConstants.MESSAGE_API_KEY_INVALID, HttpStatus.UNAUTHORIZED);
    }

    return chain.filter(exchange);
    });
    }

    public static class Config {
    private String baseMessage;
    private boolean preLogger;
    private boolean postLogger;

    public Config(String baseMessage, boolean preLogger, boolean postLogger) {
    this.baseMessage = baseMessage;
    this.preLogger = preLogger;
    this.postLogger = postLogger;
    }

    public String getBaseMessage() {
    return baseMessage;
    }

    public void setBaseMessage(String baseMessage) {
    this.baseMessage = baseMessage;
    }

    public boolean isPreLogger() {
    return preLogger;
    }

    public void setPreLogger(boolean preLogger) {
    this.preLogger = preLogger;
    }

    public boolean isPostLogger() {
    return postLogger;
    }

    public void setPostLogger(boolean postLogger) {
    this.postLogger = postLogger;
    }
    }
    }
    application.yml
      cloud:
    gateway:
    routes:
    - id: service_route
    uri: https://backend-url:443
    predicates:
    - Path=/api
    filters:
    - Logging
    过滤示例路径: https://backend-url:443/api/service1

    最佳答案

    我找到了解决方法。我使用了 RouteConfiguration 组件来设置路由和 GatewayFilter 类。在 RouteConfiguration 的 Bean 上,我已将特定过滤器设置为路由路径。就我而言,我使用过滤器进行身份验证。
    网关过滤器

    @RefreshScope
    @Component
    public class AuthenticationFilter implements GatewayFilter {

    final Logger LOGGER = LoggerFactory.getLogger(AuthenticationFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    ServerHttpRequest request = exchange.getRequest();

    // Make your business logic, this is a simple sample.


    if (!request.getHeaders().containsKey("x-api-key")) {
    return this.onError(exchange,"api-key missing",HttpStatus.FORBIDDEN);
    }

    return chain.filter(exchange); // Forward to route
    }

    private Mono<Void> onError(ServerWebExchange exchange, String err, HttpStatus httpStatus) {
    ServerHttpResponse response = exchange.getResponse();
    response.setStatusCode(httpStatus);
    return response.setComplete();
    }
    路由配置
    @RefreshScope
    @Configuration
    public class RouteConfiguration {

    @Value("${routes.api}")
    private String apiHost;

    @Autowired
    AuthenticationFilter authenticationFilter;

    @Bean
    public RouteLocator apiRoutes(RouteLocatorBuilder builder) {
    return builder.routes()
    .route("CHOICE A ROUTE ID",p -> p
    .path("/api/**")
    .filters(f -> f
    .filter(authenticationFilter) // You can add more filters here.
    .stripPrefix(1))
    .uri(apiHost))
    .build();
    }

    }

    关于java - 如何使用 Spring Cloud Gateway 自定义过滤器来过滤每个请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63080959/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com