Spring Cloud Gateway SSL异常:No subject alternative names present 求助
解决Spring Cloud Gateway 3.x SSL握手异常:No subject alternative names present
这个错误的核心原因是:谷歌云集群微服务的SSL证书中,Subject Alternative Name(SAN)字段未包含网关请求目标的域名/IP,导致SSL握手时主机名校验失败。以下是不同场景下的可行解决方法:
方案一:修复证书配置(生产环境推荐)
这是根治问题的方案,需确保谷歌云侧微服务的SSL证书包含网关访问时使用的目标域名或IP:
- 如果使用谷歌云负载均衡(GCLB)暴露微服务,在配置SSL证书时,将网关访问的域名/IP添加到证书的SAN字段中;
- 如果使用服务网格(如Istio)管理微服务证书,调整证书签发配置,把目标服务的访问域名/IP纳入SAN列表;
- 证书更新后,网关使用证书包含的域名/IP发起请求,即可通过SSL校验。
方案二:针对Spring Cloud Gateway配置自定义SSL上下文(测试/非生产环境)
若暂时无法修改证书,可通过配置Gateway的Reactor Netty HttpClient来跳过主机名校验(注意:此方法会降低安全性,仅适用于测试环境):
方法1:通过代码配置自定义HttpClient
创建配置类,覆盖Gateway默认的HttpClient,忽略SSL主机名校验:
import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import org.springframework.cloud.gateway.config.HttpClientCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import reactor.netty.http.client.HttpClient; @Configuration public class GatewaySslConfig { @Bean public HttpClientCustomizer httpClientCustomizer() { return httpClient -> { try { SslContext sslContext = SslContextBuilder.forClient() .trustManager(InsecureTrustManagerFactory.INSTANCE) .build(); return httpClient.secure(sslSpec -> sslSpec .sslContext(sslContext) .handlerConfigurator(sslHandler -> sslHandler.engine().setHostnameVerifier((hostname, session) -> true) ) ); } catch (Exception e) { throw new RuntimeException("Failed to configure SSL context", e); } }; } }
方法2:通过配置文件简化配置(仅信任所有证书,需结合主机名忽略)
在application.yml中添加以下配置,信任所有证书,再配合代码中的HostnameVerifier配置:
spring: cloud: gateway: httpclient: ssl: use-insecure-trust-manager: true
方案三:通过本地域名映射绕过校验(测试环境)
如果网关使用IP访问微服务,而证书的SAN包含对应域名,可在本地hosts文件添加映射:
- 找到本地
hosts文件(Windows:C:\Windows\System32\drivers\etc\hosts;Linux/Mac:/etc/hosts); - 添加一行:
[微服务IP] [证书中包含的域名],例如:10.123.45.67 microservice.example.com; - 修改网关路由的
uri为https://microservice.example.com,此时SSL校验会匹配证书中的SAN域名,从而通过握手。
为什么之前的方法无效?
你之前修改普通WebClient或全局HostnameVerifier未生效,是因为Spring Cloud Gateway内部使用独立的Reactor Netty HttpClient处理路由请求,普通WebClient的配置不会影响网关的核心请求链路,必须针对Gateway的HttpClient进行定制。
内容的提问来源于stack exchange,提问作者Subham Kr Gupta
相关产品推荐
相关产品推荐

