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

Spring微服务调用自签名证书HTTPS端点报错求助

解决"No subject alternative names present" HTTPS连接异常

错误原因

服务器使用的自签名证书未配置主题备用名称(Subject Alternative Name,SAN)。JVM在HTTPS握手时,会验证证书的SAN字段是否包含请求的域名/IP,若缺失则抛出该异常。


解决方案

方案1:重新生成带SAN的自签名证书(生产环境推荐)

若有权限修改服务器证书,这是最规范的解决方式:

  1. 创建san.cnf配置文件,指定证书的SAN信息:
    [req]
    distinguished_name = req_distinguished_name
    req_extensions = v3_req
    prompt = no
    
    [req_distinguished_name]
    CN = your-server-hostname-or-ip
    
    [v3_req]
    keyUsage = keyEncipherment, dataEncipherment
    extendedKeyUsage = serverAuth
    subjectAltName = @alt_names
    
    [alt_names]
    DNS.1 = your-server-hostname  # 替换为服务器域名
    IP.1 = your-server-ip-address # 替换为服务器IP
    
  2. 用OpenSSL生成带SAN的自签名证书:
    openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes -config san.cnf
    
  3. 替换服务器上的旧证书,重新将新证书导入JVM信任库:
    sudo keytool -importcert -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit -file server.crt -alias "server_remote-root"
    

方案2:修改本地hosts映射(测试/内部环境适用)

若通过IP访问服务器,可将IP映射到证书的CN域名:

  1. 打开本地hosts文件:
    • Linux/macOS:/etc/hosts
    • Windows:C:\Windows\System32\drivers\etc\hosts
  2. 添加映射规则:
    your-server-ip  your-server-hostname
    
  3. 微服务中使用your-server-hostname代替IP访问API端点,让请求域名与证书CN匹配。

方案3:自定义TrustManager跳过SAN验证(不推荐生产环境)

若无法修改证书或hosts,可通过代码跳过主机名验证(注意:此操作会降低安全性,仅用于内部可信环境):
在Spring中自定义RestTemplate:

import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.ssl.SSLContexts;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.security.KeyStore;

public class CustomRestTemplateConfig {
    public RestTemplate createRestTemplate() throws Exception {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);

        SSLContext sslContext = SSLContexts.custom()
                .loadTrustMaterial(trustStore, (chain, authType) -> true)
                .build();

        SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
                sslContext,
                NoopHostnameVerifier.INSTANCE
        );

        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setHttpClient(org.apache.http.impl.client.HttpClients.custom()
                .setSSLSocketFactory(socketFactory)
                .build());

        return new RestTemplate(factory);
    }
}

注册该RestTemplate到Spring容器,用于调用目标API。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 10:07:46