spring-bootspring-securityspring-security-oauth2spring-cloud-gatewayspring-filter

Insert a custom Filter in the Spring Security Filter Chain in Spring Cloud Gateway


I am working on spring cloud gateway which authenticates with OAuth2 with the help of spring security filter chain. Currently I am having an error at the login page of the OAuth2 because of some unknows authorization request not found error which I need to solve. I have figured a way out by adding a custom location header and route the user to that location when the exception occurs. Currently I am facing challenges while having the control before the spring security filter chain. Below is the code block which I have used:

 @Bean
 @Order(1)
 SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity serverHttpSecurity)
  throws Exception {
        ServerRequestCache requestCache = NoOpServerRequestCache.getInstance();
        WebFilter webFilter = new CustomWebFilter();
        serverHttpSecurity
          //.addFilterAt(webFilter, SecurityWebFiltersOrder.FIRST)
          .cors().and().headers()
          .frameOptions().disable()
          .and().requestCache().requestCache(requestCache)
          .and().csrf().disable()
          .authorizeExchange().pathMatchers("/**").authenticated()
          .and().oauth2Login()
          .and().oauth2Client()
          .and().oauth2ResourceServer().jwt();
     return serverHttpSecurity.build();
   }

Here I have tried adding the filter before the authentication, but it blocks the request and I get a null response and it doesn't route me to the login page.

.addFilterAt(webFilter, SecurityWebFiltersOrder.FIRST)

Below is my customWebFilter where I have added code to add the location heade.

public class CustomWebFilter implements WebFilter {

    @Autowired
    URIconfig uRIconfig;
    final Logger logger = LoggerFactory.getLogger(CustomWebFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
      URI location = exchange.getRequest().getURI();
      uRIconfig.setLocation(location);
      logger.info("Custom Pre Filter executed");
       return chain.filter(exchange);
    }
 }

Can somebody help me add the header or a cookie whichever possible before the request redirects to the OAuth2 login page? Or how can I user the filter?

Any help is much appreciated. Thanks in advance!


Solution

  • I solved this problem by changing the order of spring security filter chain to 5 and added an @Order(Ordered.HIGHEST_PRECEDENCE) to my custom filter. Now my filter invokes before my keycloak login page and I could add my custom implementation. Below is the changes I have made:

    Application.yml

    spring:
      security:
        filter:
          order: 5
    

    CustomWebFilter.java

    @Component
    @Order(Ordered.HIGHEST_PRECEDENCE)
    @Slf4j
    public class CustomWebFilter implements WebFilter {
    
      @Override
      public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        log.info("My Custom Web Filter.");
        return chain.filter(exchange);
      }
    }