Spring Boot 3.4.2迁移后无法从Eureka获取注册表(403错误)
我们正将应用从Spring Boot 3.3.4迁移至3.4.2,使用Netflix Eureka与API Gateway,部署在OpenShift环境。原3.3.4版本使用的application.yaml配置如下:
eureka: instance: prefer-ip-address: true hostname: api-gateway-service client: serviceUrl: defaultZone: ${EUREKA_URI:http://localhost:9092/eureka}
已将环境变量EUREKA_URI设置为http://v42rest-eureka:9092/eureka。迁移完成后,API Gateway无法转发请求至其他应用,但所有应用(包括网关)均已成功注册到Eureka。网关日志中出现如下错误:
"com.netflix.discovery.DiscoveryClient","message":"Getting all instance registry info from the eureka server"
"com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient","message":"Request execution failure with status code 403; retrying on another server if available","context":"default"}
仅在获取注册表信息时出现403错误,网关注册至Eureka的过程无异常。注意到Spring Boot 3.4.2版本中Netflix Eureka RestClient存在一些变更,想了解是否有其他用户遇到类似问题及解决方案。
不少用户在升级到Spring Boot 3.4.x(对应Spring Cloud 2023.0.4)时遇到过这个问题,核心原因是Eureka客户端的RestClient实现默认行为变更,导致获取注册表的请求缺少必要的头信息或触发了Eureka Server的CSRF防护。
以下是几种验证有效的解决方法:
关闭Eureka Server的CSRF防护:如果你的Eureka Server启用了Spring Security,Spring Boot 3.4.x可能默认开启了CSRF验证。可以在Eureka Server的配置中添加:
spring: security: csrf: enabled: false或者针对Eureka的端点配置CSRF豁免:
@Configuration public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.csrf(csrf -> csrf.ignoringRequestMatchers("/eureka/**")); return http.build(); } }为Eureka客户端添加必要请求头:Spring Boot 3.4.x中Eureka客户端的RestClient不再自动携带某些头信息,可在网关配置中添加:
eureka: client: request-headers: Authorization: ${EUREKA_AUTH_TOKEN:}如果Eureka Server有身份验证,确保配置正确的认证令牌。
切换回Jersey HttpClient:若RestClient的变更导致兼容性问题,可以强制Eureka客户端使用旧的Jersey实现,在网关的
pom.xml(Maven)或build.gradle(Gradle)中添加依赖:<!-- Maven --> <dependency> <groupId>com.netflix.eureka</groupId> <artifactId>eureka-client-jersey</artifactId> </dependency>并在配置中指定:
eureka: client: transport: type: jersey
内容的提问来源于stack exchange,提问作者manoj hyand

