【问题标题】:Make Spring Boot 2.7.x Actuator aware of X-Forwarded-Prefix header?让 Spring Boot Actuator 知道 X-Forwarded-Prefix 标头?
【发布时间】:2022-10-05 17:42:53
【问题描述】:

我们正在使用带有 spring-boot-starter-actuator 的 Spring Boot 2.7.0,我们将在 /management 上下文路径下的端口 8081 上公开它。代理设置了几个X-Forwarded-* 标头,包括设置为/serviceX-Forwarded-Prefix 标头。但是当导航到https://www.company.com/management 时,返回的是:

{
    \"_links\": {
        \"self\": {
            \"href\": \"https://www.company.com/management\",
            \"templated\": false
        },
        \"beans\": {
            \"href\": \"https://www.company.com/management/beans\",
            \"templated\": false
        },
        \"caches-cache\": {
            \"href\": \"https://www.company.com/management/caches/{cache}\",
            \"templated\": true
        },
        \"caches\": {
            \"href\": \"https://www.company.com/management/caches\",
            \"templated\": false
        },
        \"health\": {
            \"href\": \"https://www.company.com/management/health\",
            \"templated\": false
        },
        \"health-path\": {
            \"href\": \"https://www.company.com/management/health/{*path}\",
            \"templated\": true
        },
        \"info\": {
            \"href\": \"https://www.company.com/management/info\",
            \"templated\": false
        },
        \"conditions\": {
            \"href\": \"https://www.company.com/management/conditions\",
            \"templated\": false
        },
        \"configprops\": {
            \"href\": \"https://www.company.com/management/configprops\",
            \"templated\": false
        },
        \"configprops-prefix\": {
            \"href\": \"https://www.company.com/management/configprops/{prefix}\",
            \"templated\": true
        },
        \"env\": {
            \"href\": \"https://www.company.com/management/env\",
            \"templated\": false
        },
        \"env-toMatch\": {
            \"href\": \"https://www.company.com/management/env/{toMatch}\",
            \"templated\": true
        },
        \"integrationgraph\": {
            \"href\": \"https://www.company.com/management/integrationgraph\",
            \"templated\": false
        },
        \"loggers\": {
            \"href\": \"https://www.company.com/management/loggers\",
            \"templated\": false
        },
        \"loggers-name\": {
            \"href\": \"https://www.company.com/management/loggers/{name}\",
            \"templated\": true
        },
        \"heapdump\": {
            \"href\": \"https://www.company.com/management/heapdump\",
            \"templated\": false
        },
        \"threaddump\": {
            \"href\": \"https://www.company.com/management/threaddump\",
            \"templated\": false
        },
        \"metrics-requiredMetricName\": {
            \"href\": \"https://www.company.com/management/metrics/{requiredMetricName}\",
            \"templated\": true
        },
        \"metrics\": {
            \"href\": \"https://www.company.com/management/metrics\",
            \"templated\": false
        },
        \"scheduledtasks\": {
            \"href\": \"https://www.company.com/management/scheduledtasks\",
            \"templated\": false
        },
        \"sessions-sessionId\": {
            \"href\": \"https://www.company.com/management/sessions/{sessionId}\",
            \"templated\": true
        },
        \"sessions\": {
            \"href\": \"https://www.company.com/management/sessions\",
            \"templated\": false
        },
        \"mappings\": {
            \"href\": \"https://www.company.com/management/mappings\",
            \"templated\": false
        },
        \"refresh\": {
            \"href\": \"https://www.company.com/management/refresh\",
            \"templated\": false
        },
        \"features\": {
            \"href\": \"https://www.company.com/management/features\",
            \"templated\": false
        },
        \"traces\": {
            \"href\": \"https://www.company.com/management/traces\",
            \"templated\": false
        }
    }
}

由于提供了X-Forwarded-Prefix 标头,我希望响应中的href 以https://www.company.com/service 开头,但事实并非如此。我尝试像这样添加ForwardedHeaderFilter

@Bean
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilterFilterRegistrationBean() {
    ForwardedHeaderFilter forwardedHeaderFilter = new ForwardedHeaderFilter();
    FilterRegistrationBean<ForwardedHeaderFilter> bean = new FilterRegistrationBean<>(forwardedHeaderFilter);
    bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return bean;
}

但这没有什么区别。

在生成代理后面端点的链接时,如何使执行器考虑X-Forwarded-Prefix 标头?

    标签: spring-boot spring-actuator


    【解决方案1】:

    我遇到了同样的问题。我发现ManagementContextAutoConfiguration 使用单独的WebApplicationContext 如果管理端口不同。这就是为什么声明 ForwardedHeaderFilter 无效。可能是弹簧执行器有问题。我做了这个黑客,它似乎正在工作。但我希望有人能找到更好的解决方案。

    @Component
    @ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
    public class ManagementContextFactoryBeanPostProcessor
            implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
                throws BeansException {
            if (bean instanceof ManagementContextFactory managementContextFactory) {
                return (ManagementContextFactory) (parent, configurationClasses) -> {
                    var context = managementContextFactory.createManagementContext(parent, configurationClasses);
                    if (context instanceof GenericWebApplicationContext genericWebApplicationContext) {
                        genericWebApplicationContext.registerBean(ForwardedHeaderFilterRegistrationBean.class);
                    }
                    return context;
                };
            }
            return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
        }
    
        public static class ForwardedHeaderFilterRegistrationBean
                extends FilterRegistrationBean<ForwardedHeaderFilter> {
    
            public ForwardedHeaderFilterRegistrationBean() {
                setFilter(new ForwardedHeaderFilter());
                setOrder(Ordered.HIGHEST_PRECEDENCE);
            }
    
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      如果您使用 Spring Security,您可以通过端点安全配置添加 ForwardedHeaderFilter,如下所示:

      @Bean
      public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter() {
          return new WebSecurityConfigurerAdapter() {
              @Override
              protected void configure(HttpSecurity http) {
                  http.requestMatcher(EndpointRequest.toAnyEndpoint())
                      .addFilterBefore(new ForwardedHeaderFilter(), HeaderWriterFilter.class);
              }
          };
      }
      

      【讨论】:

        猜你喜欢
        • 2020-11-12
        • 2021-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-14
        • 1970-01-01
        • 2019-03-09
        相关资源
        最近更新 更多