SpringCloudGateway自定义Predict—实现根据不同域名切换不同鉴权方式

背景

项目相同的接口想同时提供给外部和内部调用,因为外部调用采用的是签名校验,内部调用采用的是token校验,因为签名校验可以有效起到防止用户多次调用同一个接口的作用,想同一个url,只是域名不同,起到不同的鉴权方式

考虑在网管层实现这一功能。

Spring Cloud Gateway自带的一些断言参数列表


项目中有用到path

         - id: openapi
          order: 2
          uri: ${domain.openapi}
          predicates:
            - Path=/openapi/**
          filters:
          - AuthorizationSignature
          - RewritePath=/openapi/(?<remaining>.*), /${remaining}
        - id: openapiInternal
          order: 1
          uri: ${domain.openapi}
          predicates:
            -Path=/openapi/v1/quota/**,/openapi/v1/area/**,/openapi/v1/quotatime/**
          filters:
          - AuthorizationToken
          - RewritePath=/openapi/(?<remaining>.*), /${remaining}

考虑到使用AbstractRoutePredicateFactory工厂类实现一个自定义的路由断言

@Component
public class DomainRoutePredicateFactory extends AbstractRoutePredicateFactory<DomainRoutePredicateFactory.Config> {

    public DomainRoutePredicateFactory() {
        super(Config.class);
    }

    private PathMatcher pathMatcher = new AntPathMatcher(".");

    public void setPathMatcher(PathMatcher pathMatcher) {
        this.pathMatcher = pathMatcher;
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new Predicate<ServerWebExchange>() {
            @Override
            public boolean test(ServerWebExchange exchange) {
                String host = exchange.getRequest().getURI().getHost();
                if(StringUtils.isBlank(host)){
                    return false;
                }

                Optional<String> optionalPattern = config.getPatterns().stream()
                        .filter(pattern -> pathMatcher.match(pattern, host)).findFirst();
                //检查请求参数中的domain是否与配置的数据相同,如果相同则允许访问,否则不允许访问
//                return host.equals(config.getDomain());
                if (optionalPattern.isPresent()) {
                    Map<String, String> variables = pathMatcher
                            .extractUriTemplateVariables(optionalPattern.get(), host);
                    ServerWebExchangeUtils.putUriTemplateVariables(exchange, variables);
                    return true;
                }

                return false;
            }
        };

    }


    /**
     * 配置yml文件填写
     * predicates:
     * - Domain=**.somehost.org,**.anotherhost.org
     * 支持多域名配置和模糊匹配
     */
    @Validated
    public static class Config {


        private List<String> patterns = new ArrayList<>();

        @Deprecated
        public String getPattern() {
            if (!CollectionUtils.isEmpty(this.patterns)) {
                return patterns.get(0);
            }
            return null;
        }

        @Deprecated
        public DomainRoutePredicateFactory.Config setPattern(String pattern) {
            this.patterns = new ArrayList<>();
            this.patterns.add(pattern);
            return this;
        }

        public List<String> getPatterns() {
            return patterns;
        }

        public DomainRoutePredicateFactory.Config setPatterns(List<String> patterns) {
            this.patterns = patterns;
            return this;
        }

        @Override
        public String toString() {
            return new ToStringCreator(this).append("patterns", patterns).toString();
        }

    }

    /**
     * 重写 shortcutFieldOrder
     * 指定顺序, 此处为内部类接收过滤器参数的属性名
     */
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("patterns");
    }

    /**
     * 重写 shortcutType 方法
     */
    @Override
    public ShortcutType shortcutType() {
        return ShortcutType.GATHER_LIST;
    }

}

实现了根据不同域名进行断言,并支持多个域名和模糊域名匹配。

yam文件改为

 - id: openapi
          order: 2
          uri: ${domain.openapi}
          predicates:
            - Path=/openapi/**
            - Domain=gateway-api.**
#            - name: Domain
#              args:
#                patterns: gateway-api.newayz.com,lbi-api.newayz.com
          filters:
          - AuthorizationSignature
          - RewritePath=/openapi/(?<remaining>.*), /${remaining}
        - id: openapiInternal
          order: 1
          uri: ${domain.openapi}
          predicates:
            - Path=/openapi/v1/quota/**, /openapi/v1/area/**,/openapi/v1/quotatime/**
          filters:
          - AuthorizationToken
          - RewritePath=/openapi/(?<remaining>.*), /${remaining}

两种配置都可以实现根据域名做不同的路由。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值