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

Spring Boot+Angular集群部署访问health/prometheus端点报401问题

问题现象

项目采用Spring Boot作为后端、Angular作为前端,需对接Prometheus及健康检查端点获取服务状态与指标数据,本地开发环境运行无异常,部署至测试集群后访问对应端点出现401未授权错误,当前项目处于开发/测试阶段。

现有配置信息

后端Spring Boot配置

server.port=8085
management.health.defaults.enabled=false
management.endpoint.health.show-details="ALWAYS"
management.server.port=${management.port:1234}
management.endpoints.enabled-by-default=true
management.endpoints.web.base-path=/
management.endpoints.web.exposure.include=health, prometheus

前端Angular配置

登录功能正常,集群部署后使用相对路径访问8085端口后端服务无异常,但登录后仪表盘页面调用Actuator的health、prometheus端点时触发异常,当前前端硬编码的端点地址为:

healthUrl: "http://localhost:1234/health"
metricsUrl: "http://localhost:1234/prometheus"

Spring Security安全配置

@Configuration
@EnableWebSecurity
public class ActuatorWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .cors().configurationSource(corsConfigurationSource())
                .and()
                .authorizeRequests()
                .requestMatchers(EndpointRequest.to(HealthEndpoint.class, InfoEndpoint.class)).permitAll()
                .antMatchers("/**").authenticated()
                .and().httpBasic()
                .and()
                .addFilterBefore(new ForwardedHeaderFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowCredentials(true);
        configuration.setAllowedMethods(Arrays.asList("GET","POST","OPTIONS"));
        configuration.setAllowedHeaders(Collections.singletonList("*"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}
401异常根因
  • 前端地址硬编码错误:本地开发时前后端都运行在开发者本机,写localhost:1234可以直接访问本地启动的Actuator端口;部署到测试集群后,浏览器侧的localhost指向的是访问用户的个人电脑,请求根本无法到达集群内的后端服务,就算网络通了也会因为鉴权上下文不共享、跨域被拦截。
  • Security放行规则缺失:当前安全配置仅放行了Health、Info两个Actuator端点,Prometheus端点未加入匿名放行列表,会匹配/**的认证规则,未携带有效认证凭证的请求直接返回401。
  • 管理端口安全链不生效:Spring Boot配置独立的management.server.port后,Actuator端点默认使用独立的安全过滤链,当前自定义的WebSecurityConfigurerAdapter没有指定加载顺序,配置仅对8085业务端口生效,1234管理端口仍走默认的全认证规则。
  • CORS配置互斥:CORS规则同时配置allowedOrigins="*"和allowCredentials=true,违反浏览器跨域安全规范,浏览器会直接拦截带凭证的跨域请求,表现和401异常一致。
排查思路
  • 先确认请求实际去向:打开浏览器开发者工具的网络面板,查看报错请求的目标地址,确认是否仍在请求用户本地的1234端口,先排除地址硬编码导致的请求发错位置问题。
  • 集群内直连测试端点:登录集群后端节点,执行curl http://127.0.0.1:1234/health、curl http://127.0.0.1:1234/prometheus,不带任何认证头测试返回结果,如果直连也返回401,说明问题出在后端安全配置本身,和前端逻辑无关。
  • 验证安全链加载范围:开启Spring Security的debug日志,查看1234端口收到的请求是否匹配自定义的授权规则,是否被默认安全过滤器拦截。
  • 验证跨域配置有效性:模拟前端域名发起OPTIONS预检请求,检查返回的跨域响应头是否符合规范,排除CORS拦截导致的异常。
解决方案
  • 修正前端端点配置:删除硬编码的localhost地址,将1234端口的Actuator端点通过集群Ingress/网关和业务接口做同域名代理,前端改用相对路径配置端点(当前配置设置了management.endpoints.web.base-path=/,直接配置为/health、/prometheus即可),从根源避免跨域和地址失效问题。
  • 补全端点放行规则:将PrometheusEndpoint加入匿名放行列表,修改授权配置代码:
.requestMatchers(EndpointRequest.to(HealthEndpoint.class, InfoEndpoint.class, PrometheusEndpoint.class)).permitAll()
  • 修正CORS配置冲突:同域代理场景下直接删除Actuator路径的CORS配置即可;如果确实需要跨域访问,明确配置允许的前端域名,不要用通配符*搭配allowCredentials=true。
  • 保证安全配置对管理端口生效:给自定义安全配置类添加@Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER)注解,让自定义安全规则优先加载到Actuator管理端口上,避免管理端口走默认认证逻辑。
  • 开发测试阶段快速验证可以直接关闭Actuator的安全校验,在配置文件添加:
management.endpoints.web.security.enabled=false

注意:生产环境禁止直接关闭Actuator安全校验,Prometheus端点包含服务内部敏感运行指标,需配置IP白名单或专用认证凭证做访问控制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:45:33