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

如何让Spring Security解析Eureka注册服务名作为JWT的issuer-uri

问题根因

Spring Security 自动装配的默认 JwtDecoder 使用标准 JDK HTTP 客户端发起 OIDC 元数据请求,未集成 Spring Cloud 负载均衡能力,无法识别 Eureka 注册中心的服务名,因此抛出 UnknownHostException 异常。

解决方案

步骤1:添加负载均衡依赖

Spring Cloud 2020.0+ 版本已移除 Ribbon,使用 Spring Cloud LoadBalancer 作为负载均衡组件,添加对应依赖:

<!-- Maven 依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

如果使用旧版本 Spring Cloud 且依赖 Ribbon,替换为 spring-cloud-starter-netflix-ribbon 即可。

步骤2:配置支持负载均衡的HTTP客户端

以 RestTemplate 为例:

@Configuration
public class RestTemplateConfig {
    @Bean
    @LoadBalanced
    public RestTemplate loadBalancedRestTemplate() {
        return new RestTemplate();
    }
}

如果偏好使用 WebClient,配置如下:

@Configuration
public class WebClientConfig {
    @Bean
    @LoadBalanced
    public WebClient.Builder loadBalancedWebClientBuilder() {
        return WebClient.builder();
    }
}

步骤3:自定义JwtDecoder替换默认实现

使用支持负载均衡的HTTP客户端构建 JwtDecoder,替换Spring Security自动装配的默认实现:

基于RestTemplate的实现

@Configuration
public class JwtConfig {
    @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
    private String issuerUri;

    private final RestTemplate loadBalancedRestTemplate;

    public JwtConfig(RestTemplate loadBalancedRestTemplate) {
        this.loadBalancedRestTemplate = loadBalancedRestTemplate;
    }

    @Bean
    @Lazy // 可选:如果启动时Eureka服务拉取未完成,添加懒加载避免初始化异常
    public JwtDecoder jwtDecoder() {
        NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withIssuerLocation(issuerUri)
                .restOperations(loadBalancedRestTemplate)
                .build();
        
        // 若JWT中实际iss声明与服务名形式的issuer-uri不一致,需显式指定正确的iss校验值,示例如下:
        // OAuth2TokenValidator<Jwt> validator = JwtValidators.createDefaultWithIssuer("http://实际认证服务地址/auth/realms/books");
        // jwtDecoder.setJwtValidator(validator);
        
        return jwtDecoder;
    }
}

基于WebClient的实现

@Configuration
public class JwtConfig {
    @Bean
    @Lazy
    public JwtDecoder jwtDecoder(WebClient.Builder loadBalancedWebClientBuilder, 
                                 @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}") String issuerUri) {
        return NimbusJwtDecoder.withIssuerLocation(issuerUri)
                .webClient(loadBalancedWebClientBuilder.build())
                .build();
    }
}

注意事项

  • 必须保证JWT携带的iss声明值与JwtDecoder配置的校验值一致,否则会出现JWT issuer校验失败问题。如果认证服务返回的JWT中iss为IP/域名形式,需要在自定义JwtDecoder时显式指定对应iss校验值。
  • 若启动时仍出现服务名解析失败,可给JwtDecoder Bean添加@Lazy注解,延迟初始化到首次使用时再拉取OIDC元数据,确保Eureka服务列表已拉取完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:45:06