title: How to use a Spring Cloud Gateway Custom Filter to filter every request?
body: <p>It's my first time at Spring Cloud Gateway implementation.</p>
  <p>I need filter every request and apply a filter validation on some paths. Following the  <a href="https://www.baeldung.com/spring-cloud-custom-gateway-filters" rel="nofollow noreferrer">Baeldung Custom Filters tutorial</a> I make a simple application to filter requests.</p>
  <p>The application must release paths like <code>/actuator/health</code> and validate specific paths to backend service. So far, I've implemented a <code>GlobalFilter</code> and a <code>GatewayFilterFactory</code>. The Global filter is called every request but the GatewayFilter is called just once when application starts, that way I can't make the auth logic to every request. The auth logic is about a specific header field. So, my grained questions are:</p>
  <ol>
  <li>How validate every request with a specific path?</li>
  <li>How refuse a request and send a error message?</li>
  </ol>
  <p><strong>GlobalFilter</strong></p>
  <pre><code>@Component
  public class LoggingGlobalPreFilter implements GlobalFilter {
  
      final Logger LOGGER = LoggerFactory.getLogger(LoggingGlobalPreFilter.class);
  
      @Override
      public Mono&lt;Void&gt; filter(
              ServerWebExchange exchange,
              GatewayFilterChain chain) {
          LOGGER.info(&quot;Global Pre Filter executed&quot;);
          return chain.filter(exchange);
      }
  
  }
  </code></pre>
  <p><strong>GatewayFilter</strong></p>
  <pre><code>@Component
  public class LoggingGatewayFilterFactory extends
          AbstractGatewayFilterFactory&lt;LoggingGatewayFilterFactory.Config&gt; {
  
      final Logger LOGGER =
              LoggerFactory.getLogger(LoggingGatewayFilterFactory.class);
  
      public LoggingGatewayFilterFactory() {
          super(Config.class);
      }
  
      private Mono&lt;Void&gt; 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(&quot;x-header&quot;);
      }
  
      @Override
      public GatewayFilter apply(Config config) {
          LOGGER.info(&quot;M=apply, Msg=Applying Gateway Filter....&quot;);
          return ((exchange, chain) -&gt; {
              LOGGER.info(&quot;M=apply, Msg=Applying Gateway Filter....&quot;); // 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;
          }
      }
  }
  </code></pre>
  <p><strong>application.yml</strong></p>
  <pre><code>  cloud:
      gateway:
        routes:
        - id: service_route
          uri: https://backend-url:443
          predicates:
            - Path=/api
          filters:
           - Logging
  </code></pre>
  <p>Example path to filter: <code>https://backend-url:443/api/service1</code></p>