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

Eureka客户端注册时认证失败问题求助

Eureka Client注册401错误解决方案

问题背景

已搭建带Spring Security认证的Eureka Server,控制台可正常登录,但客户端注册时持续返回401错误,无法完成注册。

现有配置

Eureka Server核心代码

启动类:

@SpringBootApplication
@EnableEurekaServer
public class DiscoveryServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(DiscoveryServerApplication.class, args);
    }
}

Security配置类:

@Configuration
public class WebConfig {

    @Value("${eureka.username}")
    private String username;
    @Value("${eureka.password}")
    private String password;

    @Bean
    public static PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf()
                .disable()
                .authorizeHttpRequests()
                .anyRequest()
                .authenticated()
                .and()
                .httpBasic()
                .and()
                .formLogin();

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        UserDetails user = User
                .withUsername(username)
                .password(encoder.encode(password))
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(user);
    }
}

application.properties:

eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
server.port=8761

eureka.username=eureka
eureka.password=password

spring.security.user.name=eureka
spring.security.user.password=password

eureka.instance.metadata-map.user.name: ${spring.security.user.name}
eureka.instance.metadata-map.user.password: ${spring.security.user.password}

Eureka Client配置

application.properties:

eureka.client.serviceUrl.defaultZone = http://eureka:password@localhost:8761/eureka
server.port=8081
spring.application.name=service-name

报错信息

2023-10-22T17:03:40.958+02:00  WARN 2528 --- [nfoReplicator-0] c.n.d.s.t.d.RetryableEurekaHttpClient    : Request execution failure with status code 401; retrying on another server if available
2023-10-22T17:03:40.959+02:00  WARN 2528 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_ORDER-SERVICE/darlyn:order-service:8081 - registration failed Cannot execute request on any known server
com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server

已尝试方案

  • 配置eureka.instance.metadata-map.user.name和password
  • 禁用CSRF
  • 添加自定义RestTemplateTransportClientFactories Bean

核心问题分析

错误根源是Eureka Server端密码编码器不匹配:配置类中同时定义了BCryptPasswordEncoder Bean,但在userDetailsService中使用了PasswordEncoderFactories.createDelegatingPasswordEncoder(),两者编码规则不一致,导致客户端的密码验证失败。此外,冗余的Security配置也会干扰Eureka注册流程。

修复方案

1. 修正Eureka Server的Security配置

统一密码编码器,并优化Security规则,仅保留Eureka注册所需的认证方式:

@Configuration
public class WebConfig {

    @Value("${eureka.username}")
    private String username;
    @Value("${eureka.password}")
    private String password;

    // 统一使用BCryptPasswordEncoder
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeHttpRequests(auth -> auth
                        // 放行Eureka核心端点,确保注册请求可正常通过认证
                        .requestMatchers("/eureka/**").authenticated()
                        .anyRequest().authenticated()
                )
                .httpBasic(); // 移除formLogin,Eureka客户端仅需httpBasic认证

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        // 使用统一的BCryptPasswordEncoder编码密码
        UserDetails user = User
                .withUsername(username)
                .password(passwordEncoder().encode(password))
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(user);
    }
}

2. 精简Eureka Server的application.properties

删除冗余配置,自定义UserDetailsService后,spring.security.user.*配置不再生效:

eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
server.port=8761

# 仅保留自定义认证的账号密码
eureka.username=eureka
eureka.password=password

3. 验证客户端配置

保持客户端defaultZone格式不变,确保账号密码与Server端一致:

eureka.client.serviceUrl.defaultZone = http://eureka:password@localhost:8761/eureka
server.port=8081
spring.application.name=service-name

版本兼容说明

无需降级版本,当前使用的Spring Boot 3.1.4 + Spring Cloud 2022.0.3(Eureka 4.0.3)是稳定兼容版本,问题出在配置细节而非版本本身。

验证步骤

  1. 重启Eureka Server,确认启动无报错
  2. 启动Eureka Client,观察日志是否出现registration status: 204的成功提示
  3. 访问Eureka控制台(http://localhost:8761),确认客户端已成功注册

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:15:31