当前位置: 首页 > 知识库问答 >
问题:

Spring Cloud Gateway自定义网关过滤器不工作

闻人飞翼
2023-03-14

我试图调试我的应用程序,但调试器没有击中此代码块。这是我的自定义网关过滤器。

@RefreshScope
@Component
public class AuthorizationHeaderFilter extends 
           AbstractGatewayFilterFactory<AuthorizationHeaderFilter.Config> {

@Autowired
Environment environment;

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

public static class Config {
}

@Override
public GatewayFilter apply(Config config) {
    return ((exchange, chain) -> {

        ServerHttpRequest request = exchange.getRequest();

        if(!request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) {
            return onError(exchange, "No authorization header", HttpStatus.UNAUTHORIZED);
        }

        String token = Objects.requireNonNull(request.getHeaders().get(HttpHeaders.AUTHORIZATION))
                .get(0).replace("Bearer","");

        if(isJwtValid(token))
            return onError(exchange, "JWT Token is not valid", HttpStatus.UNAUTHORIZED);

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

private Mono<Void> onError(ServerWebExchange exchange, String error, HttpStatus status) {
    ServerHttpResponse response = exchange.getResponse();

    response.setStatusCode(status);
    return response.setComplete();
}

private boolean isJwtValid(String token) {
    boolean returnValue = true;

    String subject = Jwts.parser().setSigningKey(environment.getProperty("token.secret")).parseClaimsJws(token)
            .getBody().getSubject();

    if(subject == null || subject.isEmpty())
        returnValue = false;

    return returnValue;
}
}

下面是这个过滤器的配置

spring.cloud.gateway.routes[0].id=users-status-check
spring.cloud.gateway.routes[0].uri=lb://users-ws
spring.cloud.gateway.routes[0].predicates[0]=Path=/users-ws/users/status
spring.cloud.gateway.routes[0].predicates[1]=Method=GET
spring.cloud.gateway.routes[0].predicates[2]=Header=Authorization, Bearer (.*)
spring.cloud.gateway.routes[0].filters[0]=RewritePath=/users-ws/(?<segment>.*), /${segment}
spring.cloud.gateway.routes[0].filters[1]=AuthorizationHeaderFilter

当尝试发送请求时,此endpoint不会启动调试器或将日志打印到控制台。我在这里错过了什么。谢谢你。

如果我在主应用程序中创建AuthorizationHeaderFilter的bean,如下所示

@SpringBootApplication
public class ApiGatewayApplication {

   public static void main(String[] args) {
       SpringApplication.run(ApiGatewayApplication.class, args);
   }


   @Bean
   public AuthorizationHeaderFilter authorizationHeaderFilter() {
    return new AuthorizationHeaderFilter();
   }
}

应用程序在启动时引发此错误

org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'authorizationHeaderFilter' defined in com.springcloud.photoapp.api.ApiGateway.ApiGatewayApplication: @Bean definition illegally overridden by existing bean definition: Root bean: class [org.springframework.aop.scope.ScopedProxyFactoryBean];

我还为云api网关设置了日志级别来调试,下面是日志

 Mapping [Exchange: GET http://localhost:8764/users-ws/users/status] to 
 Route{id='ReactiveCompositeDiscoveryClient_USERS-WS', uri=lb://USERS-WS, 
 order=0, predicate=Paths: [/users-ws/**], match trailing slash: true, 
 gatewayFilters=[[[RewritePath /users-ws/(?<remaining>.*) = '/${remaining}'], 
 order = 1]], metadata={}}
 
 RouteDefinition users-status-check applying {_genkey_0=/users- 
 ws/users/status} to Path
 RouteDefinition users-status-check applying {_genkey_0=GET} to Method
 RouteDefinition users-status-check applying {_genkey_0=Authorization, 
 _genkey_1=Bearer (.*)} to Header
 RouteDefinition users-status-check applying filter {_genkey_0=/users-ws/(? 
 <segment>.*), _genkey_1=/${segment}} to RewritePath
 RouteDefinition users-status-check applying filter {} to 
 AuthorizationHeaderFilter

共有1个答案

唐兴思
2023-03-14

嘿,我通过创建如下所示的RouteLocator@bean来解决这个问题。现在,当我在调试器模式下发出请求时,我可以点击AuthorizationHeaderFilter中的apply方法

@SpringBootApplication
public class ApiGatewayApplication {

   public static void main(String[] args) {
       SpringApplication.run(ApiGatewayApplication.class, args);
   }

   @Bean
   public RouteLocator routeLocator(RouteLocatorBuilder rlb, AuthorizationHeaderFilter 
   authorizationHeaderFilter) {

       return rlb
               .routes()
               .route(p -> p
                   .path("/users-ws/users/status")
                   .filters(f -> f.removeRequestHeader("Cookie")
                           .rewritePath("/users-ws/(?<segment>.*)", "/$\\{segment}")
                           .filter(authorizationHeaderFilter.apply(new 
                            AuthorizationHeaderFilter.Config())))
                .uri("lb://users-ws")
            )
            .build();
     }
 }
 类似资料:
  • 演示在网关追加一个header public class CustomFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 演示在网关追加heade

  • SOFARPC 提供了一套良好的可扩展性机制,为各个模块提供 SPI 的能力。 SOFARPC 对请求与响应的过滤链处理方式是通过多个过滤器 Filter 来进行具体的拦截处理,该部分可由用户自定义 Filter 扩展,自定义 Filter 的执行顺序在内置 Filter 之后。具体方式如下: Bolt Filter 新建自定义 Filter 。 public class CustomFilter

  • 问题内容: 我试图在Log4J2中实现和配置自定义过滤器- 基于ThresholdFilter,但打算做更多。我已经看到了有关自定义追加程序的主题,这些主题遵循相同的插件注释语法,但是还没有找到有关自定义拟合程序的主题。 MyCustomFilter.java (基于ThresholdFilter) log4j2.xml LoggingRunner.java 配置语法似乎与Apache文档中的语法

  • 本文向大家介绍Django 自定义过滤器,包括了Django 自定义过滤器的使用技巧和注意事项,需要的朋友参考一下 示例 过滤器允许您将函数应用于变量。此函数可以使用0或1参数。语法如下: 过滤器可以链接在一起,因此非常有效: 如果将其翻译成python,上面的代码行将给出以下内容: 在此示例中,我们将编写一个verbose_name适用于模型(实例或类)或QuerySet的自定义过滤器。它将返回

  • Dorado支持在Client或Server端创建自定义的过滤器并指定过滤器的优先级生成过滤器链路。 Dorado支持全局生效的Filter和单个配置生效的Filter,具体使用方式见下面说明。 1.过滤器接口定义 package com.meituan.dorado.rpc.handler.filter; /** * 过滤器接口, 可自行实现 * * 全局生效Filter,通过SPI配置