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

如何限制checkServerTrusted仅在自有服务器连接初始化时执行

问题核心原因

你当前自定义的checkServerTrusted被谷歌地图触发,本质是你的自定义TrustManager配置被全局生效,或者所有OkHttpClient实例都复用了带该配置的Builder,谷歌地图SDK内部发起网络请求时也用到了这套配置。


实现方案

方案1:隔离OkHttpClient实例(最推荐,改造成本最低)

  • 不要调用OkHttpClient.setDefault()之类的方法将自定义的OkHttpClient设为全局默认实例,你当前代码中生成的带自定义TrustManager的OkHttpClient,仅传给访问自有服务的Retrofit使用即可。
  • 谷歌地图SDK内部会使用自己默认的OkHttpClient实例,不会触发你的自定义校验逻辑。

方案2:checkServerTrusted内增加域名过滤逻辑

如果确实需要全局配置自定义TrustManager,可以在校验前先判断当前请求的域名是否在自有服务器白名单内,仅匹配时才执行自定义校验,其他场景直接走系统默认校验即可:

public static OkHttpClient.Builder getCustomOkHttpClient() {
    try {
        // 自有服务器域名白名单,自行替换为实际域名
        List<String> selfHostWhitelist = Arrays.asList("api.your-domain.com", "res.your-domain.com");
        
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(
                TrustManagerFactory.getDefaultAlgorithm());
        tmf.init((KeyStore) null);

        TrustManager[] trustManagers = tmf.getTrustManagers();
        final X509ExtendedTrustManager origTrustmanager = (X509ExtendedTrustManager) trustManagers[0];

        TrustManager[] wrappedTrustManagers = new TrustManager[]{
                new X509ExtendedTrustManager() {
                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return origTrustmanager.getAcceptedIssuers();
                    }

                    @Override
                    public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                        origTrustmanager.checkClientTrusted(certs, authType);
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                        origTrustmanager.checkServerTrusted(certs, authType);
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
                        if (socket instanceof SSLSocket) {
                            SSLSession session = ((SSLSocket) socket).getSession();
                            String peerHost = session.getPeerHost();
                            // 仅白名单域名走自定义校验逻辑
                            if (selfHostWhitelist.contains(peerHost)) {
                                // 此处可加入你自己的校验逻辑
                                origTrustmanager.checkServerTrusted(chain, authType, socket);
                                return;
                            }
                        }
                        // 非自有域名直接走系统默认校验
                        origTrustmanager.checkServerTrusted(chain, authType, socket);
                    }

                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
                        origTrustmanager.checkClientTrusted(chain, authType, socket);
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException {
                        SSLSession session = engine.getHandshakeSession();
                        if (session != null) {
                            String peerHost = session.getPeerHost();
                            if (selfHostWhitelist.contains(peerHost)) {
                                origTrustmanager.checkServerTrusted(chain, authType, engine);
                                return;
                            }
                        }
                        origTrustmanager.checkServerTrusted(chain, authType, engine);
                    }

                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException {
                        origTrustmanager.checkClientTrusted(chain, authType, engine);
                    }
                }
        };
        // 将自定义TrustManager绑定到OkHttpClient
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, wrappedTrustManagers, new SecureRandom());
        return new OkHttpClient.Builder()
                .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) wrappedTrustManagers[0]);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

方案3:用CertificatePinner替代全局自定义TrustManager

如果你的需求仅为对自有服务器做证书钉住/校验,不需要自定义全局信任逻辑,可以直接使用OkHttp自带的CertificatePinner功能,仅针对自有域名配置校验规则,完全不会影响其他第三方SDK的网络请求:

val client = OkHttpClient.Builder()
    .certificatePinner(
        CertificatePinner.Builder()
            // 仅给自有域名配置证书公钥哈希
            .add("api.your-domain.com", "sha256/替换为你自己的证书公钥哈希")
            .build()
    )
    .build()

val retrofit = Retrofit.Builder()
    .baseUrl(baseUrl)
    .client(client)
    .addConverterFactory(GsonConverterFactory.create(gson))
    .build()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 16:36:02