美文网首页Spring Cloud
聊聊spring cloud gateway的XForwarde

聊聊spring cloud gateway的XForwarde

作者: go4it | 来源:发表于2018-05-31 23:43 被阅读183次

    本文主要研究spring cloud gateway的XForwardedHeadersFilter

    GatewayAutoConfiguration

    spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java

    @Configuration
    @ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
    @EnableConfigurationProperties
    @AutoConfigureBefore(HttpHandlerAutoConfiguration.class)
    @AutoConfigureAfter({GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class})
    @ConditionalOnClass(DispatcherHandler.class)
    public class GatewayAutoConfiguration {
        //......
        @Bean
        @ConditionalOnProperty(name = "spring.cloud.gateway.x-forwarded.enabled", matchIfMissing = true)
        public XForwardedHeadersFilter xForwardedHeadersFilter() {
            return new XForwardedHeadersFilter();
        }
        //......
    }
    

    默认注册了XForwardedHeadersFilter

    XForwardedHeadersFilter

    spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilter.java

    @ConfigurationProperties("spring.cloud.gateway.x-forwarded")
    public class XForwardedHeadersFilter implements HttpHeadersFilter, Ordered {
        //......
        @Override
        public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) {
            ServerHttpRequest request = exchange.getRequest();
            HttpHeaders original = input;
            HttpHeaders updated = new HttpHeaders();
    
            original.entrySet().stream()
                    .forEach(entry -> updated.addAll(entry.getKey(), entry.getValue()));
    
            if (isForEnabled()) {
                String remoteAddr = request.getRemoteAddress().getAddress().getHostAddress();
                List<String> xforwarded = original.get(X_FORWARDED_FOR_HEADER);
                // prevent duplicates
                if (remoteAddr != null &&
                        (xforwarded == null || !xforwarded.contains(remoteAddr))) {
                    write(updated, X_FORWARDED_FOR_HEADER, remoteAddr, isForAppend());
                }
            }
    
            String proto = request.getURI().getScheme();
            if (isProtoEnabled()) {
                write(updated, X_FORWARDED_PROTO_HEADER, proto, isProtoAppend());
            }
    
            if (isPortEnabled()) {
                String port = String.valueOf(request.getURI().getPort());
                if (request.getURI().getPort() < 0) {
                    port = String.valueOf(getDefaultPort(proto));
                }
                write(updated, X_FORWARDED_PORT_HEADER, port, isPortAppend());
            }
    
            if (isHostEnabled()) {
                String host = toHostHeader(request);
                write(updated, X_FORWARDED_HOST_HEADER, host, isHostAppend());
            }
    
            return updated;
        }
    
        //......
    }
    
    • 如果spring.cloud.gateway.x-forwarded.for-enabled为true,则会写入X-Forwarded-For
    • 如果spring.cloud.gateway.x-forwarded.proto-enabled为true,则会写入X-Forwarded-Proto
    • 如果spring.cloud.gateway.x-forwarded.port-enabled为true,则会写入X-Forwarded-Port
    • 如果spring.cloud.gateway.x-forwarded.host-enabled为true,则会写入X-Forwarded-Host

    每个enable属性都有一个append属性,用来决定是否是添加还是追加

        private void write(HttpHeaders headers, String name, String value, boolean append) {
            if (append) {
                headers.add(name, value);
                // these headers should be treated as a single comma separated header
                List<String> values = headers.get(name);
                String delimitedValue = StringUtils.collectionToCommaDelimitedString(values);
                headers.set(name, delimitedValue);
            } else {
                headers.set(name, value);
            }
        }
    

    如果是append,则逗号分隔写入headers,如果不是则是采取set操作。

    配置

        {
          "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter",
          "defaultValue": true,
          "name": "spring.cloud.gateway.x-forwarded.enabled",
          "description": "If the XForwardedHeadersFilter is enabled.",
          "type": "java.lang.Boolean"
        },
        {
          "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter",
          "defaultValue": true,
          "name": "spring.cloud.gateway.x-forwarded.for-append",
          "description": "If appending X-Forwarded-For as a list is enabled.",
          "type": "java.lang.Boolean"
        },
        {
          "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter",
          "defaultValue": true,
          "name": "spring.cloud.gateway.x-forwarded.for-enabled",
          "description": "If X-Forwarded-For is enabled.",
          "type": "java.lang.Boolean"
        },
        {
          "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter",
          "defaultValue": true,
          "name": "spring.cloud.gateway.x-forwarded.host-append",
          "description": "If appending X-Forwarded-Host as a list is enabled.",
          "type": "java.lang.Boolean"
        },
        {
          "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter",
          "defaultValue": true,
          "name": "spring.cloud.gateway.x-forwarded.host-enabled",
          "description": "If X-Forwarded-Host is enabled.",
          "type": "java.lang.Boolean"
        },
        {
          "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter",
          "defaultValue": 0,
          "name": "spring.cloud.gateway.x-forwarded.order",
          "description": "The order of the XForwardedHeadersFilter.",
          "type": "java.lang.Integer"
        },
        {
          "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter",
          "defaultValue": true,
          "name": "spring.cloud.gateway.x-forwarded.port-append",
          "description": "If appending X-Forwarded-Port as a list is enabled.",
          "type": "java.lang.Boolean"
        },
        {
          "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter",
          "defaultValue": true,
          "name": "spring.cloud.gateway.x-forwarded.port-enabled",
          "description": "If X-Forwarded-Port is enabled.",
          "type": "java.lang.Boolean"
        },
        {
          "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter",
          "defaultValue": true,
          "name": "spring.cloud.gateway.x-forwarded.proto-append",
          "description": "If appending X-Forwarded-Proto as a list is enabled.",
          "type": "java.lang.Boolean"
        },
        {
          "sourceType": "org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter",
          "defaultValue": true,
          "name": "spring.cloud.gateway.x-forwarded.proto-enabled",
          "description": "If X-Forwarded-Proto is enabled.",
          "type": "java.lang.Boolean"
        }
    

    小结

    spring cloud gateway提供了XForwardedHeadersFilter,用来决定进行路由转发的时候转发哪些X-Forwarded相关的header,同时提供append选项,用来控制是否是追加还是覆盖到header中。

    doc

    相关文章

      网友评论

        本文标题:聊聊spring cloud gateway的XForwarde

        本文链接:https://www.haomeiwen.com/subject/azocsftx.html