20 - unified Gateway - Global filter

Keywords: Spring Cloud Microservices gateway microservice

Global filter

The gateway provides 31 kinds of filters learned in the previous section, but the function of each filter is fixed. If we want to intercept requests and do our own business logic, we can't do it.

3.5.1. Global filter function

The global filter is also used to handle all requests and microservice responses entering the gateway, just like the gateway filter. The difference is that the gateway filter is defined by configuration, and the processing logic is fixed; The logic of GlobalFilter needs to be implemented by writing code.

This is defined by implementing the GlobalFilter interface.

public interface GlobalFilter {
    /**
     *  Process the current request. If necessary, pass the request to the next filter through {@ link GatewayFilterChain}
     *
     * @param exchange Request context, which can obtain request, Response and other information
     * @param chain Used to delegate requests to the next filter 
     * @return {@code Mono<Void>} Return to indicate the end of the current filter business
     */
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

Writing custom logic in filter can realize the following functions:

  • Login status judgment
  • Permission verification
  • Request current limit, etc

3.5.2. User defined global filter

Requirement: define a global filter, intercept the request, and judge whether the requested parameters meet the following conditions:

  • Whether there is authorization in the parameter,

  • Whether the authorization parameter value is admin

If both are met, release, otherwise intercept

realization:

Define a filter in the gateway:

package cn.itcast.gateway.filters;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1. Get request parameters
        MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
        // 2. Get the authorization parameter
        String auth = params.getFirst("authorization");
        // 3. Calibration
        if ("admin".equals(auth)) {
            // Release
            return chain.filter(exchange);
        }
        // 4. Interception
        // 4.1. Prohibit access and set the status code
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
        // 4.2. End processing
        return exchange.getResponse().setComplete();
    }
}

3.5.3. Filter execution sequence

The request to enter the gateway will encounter three types of filters: the filter of the current route, DefaultFilter and GlobalFilter

After requesting a route, the current route filter, DefaultFilter and GlobalFilter will be merged into a filter chain (Collection), and each filter will be executed in turn after sorting:

What are the sorting rules?

  • Each filter must specify an order value of type int. the smaller the order value, the higher the priority and the higher the execution order.
  • GlobalFilter specifies the order value by implementing the Ordered interface or adding the @ order annotation, which is specified by ourselves
  • The order of routing filter and defaultFilter is specified by Spring. By default, it is incremented from 1 in the order of declaration.
  • When the order value of the filter is the same, it will be executed in the order of defaultfilter > routing filter > globalfilter.

For details, you can view the source code:

org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters() method is to load defaultFilters first, then load filters of a route, and then merge.

The org.springframework.cloud.gateway.handler.FilteringWebHandler#handle() method will load the global filter, merge it with the previous filter, sort it according to the order, and organize the filter chain

Posted by grantp22 on Fri, 12 Nov 2021 02:43:23 -0800