Retrofit 不支持 CLEARTEXT 通信

问题描述 投票:0回答:6

我正在尝试使用 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 中分配的。

android http ssl retrofit
6个回答
141
投票

根据网络安全配置

本节中的指南仅适用于面向 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>

22
投票

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

android:usesCleartextTraffic="true"

有效!


9
投票

CLEARTEXT 消息是由于直接或通过服务器端重定向请求

http
URL(例如,以
https
开头,然后重定向到
http
)。

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

选项包括:


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


0
投票

usesCleartextTraffic

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


0
投票
您遇到的错误消息“网络安全策略不允许与 192.168.0.107 进行 CLEARTEXT 通信”,表明您的 Android 应用程序正在尝试通过未加密的连接 (HTTP) 而不是与服务器 (192.168.0.107) 进行通信加密连接 (HTTPS)。 Android 的网络安全策略,从 Android 9 (Pie) 开始,默认强制执行安全通信,并且不允许未加密的流量。

要解决此问题,您有以下几种选择:

使用 HTTPS:最安全的选项是将服务器配置为使用 HTTPS (SSL/TLS)。这涉及为您的服务器获取 SSL 证书并配置您的 Web 服务器软件(例如 Apache、Nginx)以使用 SSL。一旦您的服务器设置了 HTTPS,您就可以从 Android 应用程序安全地与其通信。

网络安全配置:如果您出于开发或测试目的需要与不安全的服务器通信,您可以创建一个网络安全配置文件,允许明文流量传输到特定域或 IP 地址。这应该仅用于开发,不建议用于生产。

在 Android 项目的 res/xml 目录中创建网络安全配置 XML 文件(例如,network_security_config.xml):

<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> <certificates src="user" /> </trust-anchors> </base-config> </network-security-config>
然后,在 AndroidManifest.xml 中引用此配置:

<application android:networkSecurityConfig="@xml/network_security_config" ... >
请谨慎使用此方法,切勿在生产环境中使用它。

使用 Android 版本较低的模拟器或设备:如果您在 Android 8.0 (Oreo) 或更低版本的物理设备或模拟器上运行应用程序,则不会遇到此问题,因为它们不会强制执行网络安全策略与较新的 Android 版本相同。然而,这不是推荐的长期解决方案,因为它没有解决潜在的安全问题。

对于生产环境,您应该始终致力于使用 HTTPS(选项 1)。应尽可能避免不安全的通信,以保护数据传输并维护安全。

© www.soinside.com 2019 - 2024. All rights reserved.