Retrofit 不支持 CLEARTEXT 通信

Posted

技术标签:

【中文标题】Retrofit 不支持 CLEARTEXT 通信【英文标题】:CLEARTEXT communication not supported on Retrofit 【发布时间】:2017-05-29 18:58:49 【问题描述】:

我正在尝试使用 Retrofit 连接到 android 上的 https 服务器。这是我的OkHttpClient

@Provides
public OkHttpClient provideContactClient()
  HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
  ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
      .tlsVersions(TlsVersion.TLS_1_2)
      .cipherSuites(CipherSuite.TLS_RSA_WITH_DES_CBC_SHA,
          CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
          CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
      .build();
  interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
  SSLSocketFactory sslSocketFactory = null;
  try 
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, null, null);
    sslSocketFactory = sslContext.getSocketFactory();
  catch (GeneralSecurityException e)
    e.printStackTrace();
  
  return new OkHttpClient.Builder()
      .addInterceptor(interceptor)
      .connectionSpecs(Collections.singletonList(spec))
      .sslSocketFactory(sslSocketFactory)
      .authenticator(new Authenticator() 
        @Override
        public Request authenticate(Route route, Response response) throws IOException 
          if(responseCount(response) >= 5)
            return null;
          
          String credential = Credentials.basic("user", "pass");
          return response.request().newBuilder().header("Authorization", credential).build();
        
      )
      .build();

但是我不断收到CLEARTEXT communication not supported: 异常

在调试RealConnection 类时,我注意到route.address() 成员没有sslSocketFactory,尽管它已在Bulider 中分配。

【问题讨论】:

您显然是在请求http URL,而不是https。或者,https URL 可能正在重定向到 http 好的,现在我在更改为 https 后得到“未找到证书路径的信任锚”。 现在,摆脱你的SSLSocketFactory 弹出同样的错误 Android 8: Cleartext HTTP traffic not permitted的可能重复 【参考方案1】:

根据网络安全配置

本节中的指南仅适用于面向 Android 8.1(API 级别 27)或更低版本的应用。从 Android 9 开始(API 28 级),默认禁用明文支持。

创建文件 res/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">Your URL(ex: 127.0.0.1)</domain>
    </domain-config>
</network-security-config>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:networkSecurityConfig="@xml/network_security_config"
        ...>
        ...
    </application>
</manifest>

或者您可以像这样直接在清单中的应用程序中设置。

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
        ...
    </application>
</manifest>

【讨论】:

@Jitendra,即使在应用程序在 Play 商店上发布后,它还能工作吗? @sohali 你需要添加应用并再次发布应用 嗨@Jitendraramoliya 我尝试了但没有解决问题,请建议其他方式。提前致谢 通常它是有效的,它是由 android it self 建议的。您需要以这种方式检查其他内容 @AnilAtri 只需在 androidmanifest.xml 文件的应用程序标签中添加 android:usesCleartextTraffic="true"【参考方案2】:

仅将此添加到清单(应用程序内部)

android:usesCleartextTraffic="true"

有效!

【讨论】:

它有效,但我担心这也会用于生产,并且可能会产生一些安全隐患【参考方案3】:

CLEARTEXT 消息是由于直接或通过服务器端重定向请求http URL(例如,以https 开头,然后重定向到http)。

就您的“未找到证书路径的信任锚”消息而言,您的服务器似乎正在使用一些 SSL 证书,而该证书在您正在测试的任何 Android 环境中都不受标准证书之一的支持。例如,您的服务器可能正在使用自签名 SSL 证书。

选项包括:

在 Android 7.0+ 上使用 network security configuration

在 Android 4.2+ 上使用 my backport of network security configuration

设置一个知道您的自签名证书的 SSLContext,然后将其附加到 OkHttp,如 this OkHttp recipe 所示

【讨论】:

我使用为我尝试访问的站点提供的证书完成了所有这些操作。还是一样的错误。 @hubert:与给你证书的人谈谈,然后和他们一起解决。【参考方案4】:

如果您请求具有 https/tls ConnectionSpec 设置的 http:// 主机,即使在旧的 Android 设备(6.0、5.0、5.1 等)中,OkHttp 库也很容易产生“不支持 CLEARTEXT 通信异常”。

【讨论】:

【参考方案5】:

usesCleartextTraffic

在 manifest.xml 文件中使用 tools:replace="android:usesCleartextTraffic"

【讨论】:

这用于拥有多个清单文件。如果您的项目包含多个清单文件,您可以在应用程序下的AndroidManifest.xml文件中使用上述代码。

以上是关于Retrofit 不支持 CLEARTEXT 通信的主要内容,如果未能解决你的问题,请参考以下文章

OkHttp:<-- HTTP FAILED:java.net.UnknownServiceException:网络安全策略不允许与 10.0.2.2 进行 CLEARTEXT 通信

iOS App 不支持http协议 App Transport Security has blocked a cleartext HTTP (http://)

什么是工具的用法:targetApi =“m”?

网络通信框架Retrofit2

安卓IPC跨进程通讯:AIDL+Retrofit——AndLinker的初步使用

基于Retrofit+RxJava 封装 Leopard 网络框架