Gateway断言工厂

back

全局过滤器


全局过滤器作用于所有路由,无需配置。通过全局过滤器可以实现对权限的统一校验,安全性验证等功能.
SpringCloudGateway内部也是通过一系列的内置过滤器对整个路由转发进行如下处理:

内置的过滤器已经可以完成大部分的功能,但是对于企业开发的一些业务功能处理,还是需要我们自己编写过滤器来实现的.定义方式是实现GlobalFilter接口。

public interface GlobalFilter {
    /**
     *  处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
     *
     * @param exchange 请求上下文,里面可以获取Request、Response等信息
     * @param chain 用来把请求委托给下一个过滤器 
     * @return {@code Mono} 返回标示当前过滤器业务结束
     */
    Mono filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

在filter中编写自定义逻辑,可以实现下列功能:

  • 登录状态判断
  • 权限校验
  • 请求限流等

自定义全局过滤器

现在我们一起通过代码的形式自定义一个过滤器,去完成统一的权限校验,开发中鉴权逻辑:

如上图,对验证用户是否已经登录鉴权的过程可以在网关统一校验。

package edu.uestc.canary.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 filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //统一鉴权逻辑
        var token = exchange.getRequest().getQueryParams().getFirst("token");
        if (!StringUtils.pathEquals("admin",token)){
          //认证失败
          log.info("认证失败了...");
          exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
          return exchange.getResponse().setComplete();
        }
        //放行
        return chain.filter(exchange);
    }
}

过滤器执行顺序

请求进入网关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter

请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器:

排序的规则是什么呢?

详细内容,可以查看源码:

org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()方法是先加载defaultFilters,然后再加载某个route的filters,然后合并。

org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法会加载全局过滤器,与前面的过滤器合并后根据order排序,组织过滤器链