SpringCloud Gateway custom assertion factory

When all officially provided assertion factories cannot meet business requirements, you can also customize assertion factories.

Add custom assertion factory class

The main points to note about the custom assertion factory are:

  • You need to declare a Springboot bean, add the annotation @Component, and the name must end with RoutePredicateFactory, which is a naming constraint.
  • If you don't name it according to the naming constraints, then the assertion factory will not be found. The prefix is ​​the assertion configured in the configuration.
  • You can directly copy the assertion factory that has been implemented in Gateway, modify the corresponding content, and avoid stepping on the pit.
  • Inherit the parent class AbstractRoutePredicateFactory and override the method.
  • You need to define a Config static inner class to receive the data of the assertion configuration.
  • In the overridden shortcutFieldOrder method, bind the properties in Config. The content of the incoming array needs to be consistent with the properties in Config.
  • In the overridden apply method, implement specific validation logic.
import com.alibaba.cloud.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

/**
 * @ClassName CustomVerifyRoutePredicateFactory
 * @Description 
 * @Author tigerkin
 * @Date 2022/3/14 15:15
 */
@Component
public class CustomVerifyRoutePredicateFactory extends AbstractRoutePredicateFactory<CustomVerifyRoutePredicateFactory.Config> {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 验证内容 key.
     */
    public static final String VERIFY_CONTENT_KEY = "verifyContentKey";

    /**
     * 验证内容 val.
     */
    public static final String VERIFY_CONTENT_VAL = "verifyContentVal";

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

    /**
     * 将签名 key 与 静态类Config中的属性进行绑定
     * 数组里面下标对应配置文件中配置
     *
     * @return
     */
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(VERIFY_CONTENT_KEY, VERIFY_CONTENT_VAL);
    }

    @Override
    public Predicate<ServerWebExchange> apply(CustomVerifyRoutePredicateFactory.Config config) {
        return new GatewayPredicate() {

            /**
             * 断言验证逻辑,返回true,则验证成功,否则失败
             *
             * @param serverWebExchange
             * @return
             */
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                HttpHeaders headers = serverWebExchange.getRequest().getHeaders();
                String headerVal = headers.getFirst(config.getVerifyContentKey());
                boolean result = StringUtils.equals(headerVal, config.getVerifyContentVal());

                log.info("========> 自定义断言配置 key:{} val:{}", config.getVerifyContentKey(), config.getVerifyContentVal());
                log.info("========> 自定义断言验证 status:{} val:{}", result, headerVal);
                return result;
            }

            @Override
            public Object getConfig() {
                return config;
            }

            @Override
            public String toString() {
                return String.format("key: %s, val: %s", config.getVerifyContentKey(), config.getVerifyContentVal());
            }
        };
    }

    /**
     * 定义静态类,接收自定义断言的配置信息
     */
    public static class Config {

        @NotNull
        private String verifyContentKey;

        @NotNull
        private String verifyContentVal;

        public String getVerifyContentKey() {
            return verifyContentKey;
        }

        public void setVerifyContentKey(String verifyContentKey) {
            this.verifyContentKey = verifyContentKey;
        }

        public String getVerifyContentVal() {
            return verifyContentVal;
        }

        public void setVerifyContentVal(String verifyContentVal) {
            this.verifyContentVal = verifyContentVal;
        }
    }
}

Configure a custom assertion factory

spring:
  cloud:
    gateway:
      routes:
        - id: user-route # 路由ID,唯一标识,自定义命名
          uri: lb://gateway-user
          predicates:
            - Path=/user-server/**
            # 自定义的断言工厂,多个参数按逗号(,)隔开,参数对应断言工厂中shortcutFieldOrder方法定义的数组,一一对应。
            - CustomVerify=verify, success 

At this point, the custom assertion factory is complete! ! !

Guess you like

Origin blog.csdn.net/weixin_42270645/article/details/123661232