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
相关产品推荐
相关产品推荐

