2

I have multiple WebFilters (Webflux Webfilter not the traditional spring MVC filter), each needs to execute some logic before response commit. Can i use multiple beforeCommit ?

for example, in filter 1 have have

  exchange.getResponse().beforeCommit(() -> {
      a();
  });

in filter 2 I have

 exchange.getResponse().beforeCommit(() -> {
  b();
});

Will both a and b get executed before response commit? If so can I control order? (I want a execute first)

user3908406
  • 1,416
  • 1
  • 18
  • 32

1 Answers1

1

The order of the beforeCommit will be the order of the filters inside which they are specified.

eg. If have a TenancyContextFilter of Order -1:

@Component
@Order(-1)
public class TenancyContextFilter implements WebFilter {

  private static final Logger LOGGER = LoggerFactory.getLogger(TenancyContextFilter.class);

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    //..some logic...
    exchange.getResponse().beforeCommit(() -> {
      return Mono.subscriberContext().doOnNext(ctx -> {
        System.out.println("Executing before commit for TenancyContextFilter");
      }).then();
    });
    return chain.filter(exchange);
  }

}

and a ScopeCheckFilter of order -2,

@Component
@Order(-2)
public class ScopeCheckFilter implements WebFilter {

  private static final Logger LOGGER = LoggerFactory.getLogger(ScopeCheckFilter.class);

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    //some logic...
    exchange.getResponse().beforeCommit(() -> {
      return Mono.subscriberContext().doOnNext(ctx -> {
        System.out.println("Executing before commit for ScopeCheckFilter");
      }).then();
    });
    return chain.filter(exchange);
  }
}

Then the ScopeCheckFilter executes before TenancyContextFilter , so as their beforeCommit logic.

Thus the logs I get, when I execute, are:

2020-07-23 13:04:09.345  INFO c.b.e.i.ImageServiceApplication          :[        ] Starting ImageServiceApplication on in1-1025453mbp with PID 98071 (/Users/Abhi/codes/image-service/out/production/classes started by 1025453 in /Users/Abhi/codes/image-service)
2020-07-23 13:04:09.347  INFO c.b.e.i.ImageServiceApplication          :[        ] No active profile set, falling back to default profiles: default
2020-07-23 13:04:10.606  INFO o.s.b.a.e.web.EndpointLinksResolver      :[        ] Exposing 2 endpoint(s) beneath base path '/actuator'
2020-07-23 13:04:10.805  INFO o.s.b.web.embedded.netty.NettyWebServer  :[        ] Netty started on port(s): 8080
2020-07-23 13:04:10.825  INFO c.b.e.i.ImageServiceApplication          :[        ] Started ImageServiceApplication in 1.741 seconds (JVM running for 2.309)
2020-07-23 13:04:14.519  INFO c.b.e.i.controller.ImageController       :[tenant1] Request received to generate SAS Token
2020-07-23 13:04:15.714  INFO c.b.e.i.s.a.AzureImageStorageService     :[tenant1] Container exists
2020-07-23 13:04:15.715  INFO c.b.e.i.s.a.AzureImageStorageService     :[tenant1] Generating SAS Token
Executing before commit for ScopeCheckFilter
Executing before commit for TenancyContextFilter

And if you have added your filters in the WebSecurity Filter Chain, then, also, it will be same as the order in which you add those filters.

eg. Below I am adding the ScopeCheckFilter first to the SecurityWebFilterChain.

  @Bean
  SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
    http
        .csrf().disable()
        //..some logic....
        ;

    http.addFilterAfter(new ScopeCheckFilter(), SecurityWebFiltersOrder.AUTHORIZATION);
    http.addFilterAfter(new TenancyContextFilter(), SecurityWebFiltersOrder.AUTHORIZATION);

    return http.build();
  }
Abhinaba Chakraborty
  • 3,488
  • 2
  • 16
  • 37