You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Spring Boot 3 Actuator识别X-Forwarded-Prefix请求头?

Spring Boot 3 Actuator 适配 X-Forwarded-Prefix 生成正确链接的解决方案

问题核心

Spring Boot 3中,仅通过添加ForwardedHeaderFilter无法让Actuator的链接生成逻辑感知到代理传递的X-Forwarded-Prefix头,且原Spring Boot 2.7基于ManagementContextFactory的 workaround 因类结构变更失效,需调整配置或自定义逻辑解决。

可行解决方案

1. 配置ForwardedHeaderFilter并调整Actuator路径映射

确保过滤器正确作用于Actuator路径,同时配合框架的转发头策略:

  • 注册优先级靠前的ForwardedHeaderFilter:
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.ForwardedHeaderFilter;

@Configuration
public class ProxyConfig {

    @Bean
    public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
        FilterRegistrationBean<ForwardedHeaderFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new ForwardedHeaderFilter());
        registrationBean.addUrlPatterns("/management/*");
        registrationBean.setOrder(-100); // 确保在其他过滤器前执行
        return registrationBean;
    }
}
  • 在application.yml中配置Actuator与服务器属性:
server:
  forward-headers-strategy: framework # 明确使用框架处理转发头
management:
  server:
    port: 8081
    base-path: /management
  endpoints:
    web:
      base-path: / # 将端点基础路径设为根,配合代理前缀拼接
      exposure:
        include: "*"

2. 自定义EndpointLinksResolver覆盖链接生成逻辑

若上述配置仍不生效,可自定义链接解析器,手动注入X-Forwarded-Prefix值:

import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointWebExtension;
import org.springframework.boot.actuate.endpoint.web.Link;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Configuration
public class ActuatorLinkConfig {

    @Bean
    public EndpointLinksResolver customEndpointLinksResolver(List<ServletEndpointWebExtension> servletExtensions, List<EndpointWebExtension<?>> webExtensions) {
        return new EndpointLinksResolver(servletExtensions, webExtensions) {
            @Override
            public WebEndpointResponse<Map<String, Link>> links() {
                WebEndpointResponse<Map<String, Link>> originalResponse = super.links();
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                String forwardedPrefix = request.getHeader("X-Forwarded-Prefix");
                
                if (forwardedPrefix != null && !forwardedPrefix.isEmpty()) {
                    Map<String, Link> modifiedLinks = new HashMap<>(originalResponse.getBody());
                    modifiedLinks.replaceAll((key, link) -> {
                        String originalHref = link.getHref();
                        String newHref = forwardedPrefix + "/management" + originalHref.substring(originalHref.indexOf("/", 1));
                        return Link.of(newHref);
                    });
                    return new WebEndpointResponse<>(modifiedLinks, originalResponse.getStatus());
                }
                return originalResponse;
            }
        };
    }
}

3. 验证效果

启动应用后通过代理访问https://www.company.com/management,查看返回JSON的_links节点,确认所有链接的href已包含/service/management前缀。


内容的提问来源于stack exchange,提问作者Johan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 16:32:23