5

I'm trying to debug my application, but debugger not hitting this code block. Here is my custom gateway filter.

@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;
}
}

And here is the configuration for this filter

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

When try to send request this endpoint it doesnt start the the debugger or print logs to the console. What i'am missing here. Thank you.

if i create the bean of AuthorizationHeaderFilter in my main application like this

@SpringBootApplication
public class ApiGatewayApplication {

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


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

Application throws this error on startup

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];

I also setted logging level to debug for cloud api gateway, here is the logs

 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
isa_toltar
  • 586
  • 5
  • 11

1 Answers1

4

Hey i was manage to solve this problem by creating a RouteLocator @Bean like below. Now when i make a request in debugger mode i can hit the apply method in AuthorizationHeaderFilter

@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();
     }
 }
isa_toltar
  • 586
  • 5
  • 11
  • 1
    I'm following the same lecture on udemy and I got stuck in the same spot. I'm still looking for a declarative solution (i.e. use the application.properties route filters declaration). Have you found any? – Jenna S Mar 22 '22 at 01:00
  • hey Jenna, what is the name of your filter class name ? if it is AuthorizationHeaderFilter rename it to AuthorizationHeaderFilterFactory and try again. – isa_toltar Mar 22 '22 at 07:08
  • I did do that even before I posted the question based on your above conversation. No change. I did notice that if I change the filter name to something non-existent (e.g. AuthorizationHeaderFilterBlah), then the gateway doesn't even start. So the declaration is indeed validated by the framework. Pre-filters and post-filters working just fine. This is still a mystery for me. – Jenna S Mar 22 '22 at 19:13
  • as @spencergibb mentioned earlier, problem with my code was the filter class naming, not sure but maybe you're problem is about version of Gateway. Probably you should create a seperate and detailed stackoverflow post. – isa_toltar Mar 23 '22 at 11:21
  • 1
    My problem was that spring.cloud.gateway.discovery.locator.enabled was set to true. It must be set to false for the declarative routes configuration. – Jenna S Mar 26 '22 at 00:36
  • oh i didn't know that interesting. – isa_toltar Mar 27 '22 at 13:01
  • @JennaS I 'm facing same problem. Have you solved it? – Yogesh Bombe Jun 01 '22 at 07:09