Сообщение CLEARTEXT не поддерживается при дооснащении

Я пытаюсь подключиться к https-серверу на Android с помощью Retrofit. Здесь мой 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() член route.address() не имеет sslSocketFactory несмотря на то, что он назначен в Bulider.

Ответ 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>

Ответ 2

Сообщение CLEARTEXT вызвано запросом URL-адреса http либо напрямую, либо через перенаправление на стороне сервера (например, начинается с https, а затем перенаправляется на http).

С точки зрения вашего сообщения "якорь доверия для пути сертификации не найден" ваш сервер, похоже, использует некоторый сертификат SSL, который не поддерживается ни одним из стандартных сертификатов в любой среде Android, на которой вы тестируете. Например, возможно, ваш сервер использует самозаверяющий сертификат SSL.

Варианты включают в себя:

Ответ 3

Кроме того, "связь CLEARTEXT, исключение не поддерживается" может быть легко воспроизведена даже на старых устройствах Android (6.0, 5.0, 5.1 и т.д.) С помощью библиотеки OkHttp, если вы запрашиваете http://хост с настройками https/tls ConnectionSpec.