Android 8: открытый HTTP-трафик не разрешен

У меня были сообщения от пользователей с Android 8, что мое приложение (которое использует внутренний канал) не показывает контент. После расследования я обнаружил следующее исключение, происходящее на Android 8:

08-29 12:03:11.246 11285-11285/ E/: [12:03:11.245, main]: Exception: IOException java.io.IOException: Cleartext HTTP traffic to * not permitted
at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:115)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:458)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
at com.deiw.android.generic.tasks.AbstractHttpAsyncTask.doConnection(AbstractHttpAsyncTask.java:207)
at com.deiw.android.generic.tasks.AbstractHttpAsyncTask.extendedDoInBackground(AbstractHttpAsyncTask.java:102)
at com.deiw.android.generic.tasks.AbstractAsyncTask.doInBackground(AbstractAsyncTask.java:88)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)

(Я удалил имя пакета, URL и другие возможные идентификаторы)

На Android 7 и ниже все работает, я не устанавливаю android:usesCleartextTraffic в манифесте (и установка его на true не помогает, это значение по умолчанию в любом случае), а также я не использую информацию о сетевой безопасности. Если я позвоню NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted(), это возвращает false для Android 8, true для более старой версии, используя тот же файл apk. Я пытался найти упоминание об этом в информации Google об Android O, но безуспешно.

44 ответа

Если вы используете ionic и получаете эту ошибку во время встроенного плагина http, необходимо сделать следующее исправление:

идти к resources/android/xml/network_security_config.xml Измените его на-

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">localhost</domain>
        <domain includeSubdomains="true">api.example.com(to be adjusted)</domain>
    </domain-config>
</network-security-config>

Это сработало для меня!

Когда приложение обменивается данными с серверами с использованием сетевого трафика открытого текста, такого как HTTP, это может повысить риск подслушивания и фальсификации содержимого. Третьи лица могут вводить несанкционированные данные или передавать информацию о пользователях. Вот почему разработчикам рекомендуется защищать только трафик, такой как HTTPS.

Но на случай, если использование открытого текста неизбежно, разработчики могут исправить ошибку,

1. Редактирование useCleartextTraffic атрибут в manifest.xml файл или

2. Добавление настроек безопасности сети

Опция 1:

В Android 6.0 появился атрибут useCleartextTraffic в элементе приложения в манифесте Android. Значение по умолчанию в Android P: “false”, Значение true указывает, что приложение намерено использовать чистый сетевой трафик.

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

Вариант 2:

Однако может показаться, что это решает проблему, но это создает угрозу целостности данных. Лучшее решение предлагается в Android 7.0 через файл конфигурации сетевой безопасности. Конфигурация безопасности сети позволяет приложению разрешать трафик открытым текстом из определенного домена.

1) Добавьте файл конфигурации безопасности сети в res/xml.

2) Добавить конфигурацию домена и установить cleartextTrafficPermitted в “true”,

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">your_domain.com</domain>
    </domain-config>
</network-security-config>

3) Добавьте конфигурацию безопасности вашей сети на ваш Android manifest.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>

После изменения API версии 9.0 получение сообщения об ошибке HTTP в открытом виде в YOUR-API.DOMAIN.COM не разрешено (targetSdkVersion="28"). в xamarin, xamarin.android и андроид студии.

Два шага для решения этой ошибки в xamarin, xamarin.android и android studio.

Шаг 1. Создайте файл resources/xml/network_security_config.xml

В network_security_config.xml

<?xml version="1.0" encoding="utf-8" ?>
<network-security-config>
  <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">mobapi.3detrack.in</domain>
  </domain-config>
</network-security-config>

Шаг 2: обновите AndroidManifest.xml -

Добавьте android:networkSecurityConfig="@xml/network_security_config" в тег приложения. например:

<application android:label="your App Name" android:icon="@drawable/icon" android:networkSecurityConfig="@xml/network_security_config">

Добавление этого параметра в заголовок решило мою проблему в apiSauce React Native

"Content-Type": "application/x-www-form-urlencoded",
  Accept: "application/json"

Открытый текст - это любая переданная или сохраненная информация, которая не зашифрована или не предназначена для шифрования.

Когда приложение обменивается данными с серверами, используя сетевой трафик в виде открытого текста, например HTTP (не https), это может повысить риск взлома и подделки контента. Третьи стороны могут вводить неавторизованные данные или утечку информации о пользователях. Вот почему разработчикам рекомендуется использовать только защищенный трафик, например HTTPS. Вот реализация и руководство по решению этой проблемы.

Попробуйте ввести в URL-адрес https:// вместо http://.

Мы столкнулись с очень похожей проблемой, и нам было сложно ее понять. Для тех незадачливых душ, которым придется с этим столкнуться, вот что мы сделали:

Приложение ionic нормально работало в браузере (Chrome и Firefox), было развернуто в магазине приложений Apple и прекрасно взаимодействовало с нашим API на AWS. Затем мы перешли к сборке Android. В эмуляторе наш запрос https API даже не будет отправлен. На физическом устройстве https-запросы также не будут отправляться (после развертывания для «внутреннего тестирования» в Google Play).

Запустили наше приложение в эмуляторе. Открыл хром, набрал «chrome: // inspect», подождал, щелкнул ссылку на экземпляр эмулятора и смог просмотреть вкладку сети. Запросы будут быстро меняться от (ожидающих) до (отмененных) без отправки на сервер.

Посмотрел весь stackoverflow, и главный совет состоял в том, чтобы отключить https с помощью workaournd cleartextPermitted, что является ужасной идеей.

Другой распространенный совет - использовать собственный http, но какой смысл использовать ionic, если нам нужно иметь 2 базы кода, а я хотел сохранить свои перехватчики http.

Добавлен файл network_security_config.xml (который, вероятно, не является строго необходимым, но удаляет предупреждение о компиляции в Android Studio.)

Проверил SSL-сертификат на наших серверах, щелкнув значок замка в браузере. Выглядело нормально. (возможно, потому, что на самом деле это не так, но у меня было ручное переопределение, которое я давно добавил и забыл). много других преследований за хвостом ...

Наконец, использовал инструмент sslshopper для проверки нашего сертификата SSL: https://www.sslshopper.com/ssl-checker.html

Оказывается, пока наш сертификат был в порядке, цепочка сертификатов - нет . В их диагностике это будет отображаться как красная сломанная стрелка.

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

Исправьте цепочку SSL:

      cat your-purchased-cert-site-com.crt > your-site.bundle.crt
cat other-org-cert-sectigoRSA-bla-bla-bla.crt >> your-site.bundle.crt
cat another-org-cert-USERTrust-bla-bla-bla.crt >> your-site.bundle.crt
cat some-final-high-level-org-cert.crt >> your-site.bundle.crt

Тогда в нашем случае для nginx на ubuntu:

поместите your-site.bundle.crt туда, где его можно использовать. (в нашем случае / var / ssl)

      update /etc/nginx/sites-available/site-name.conf:
ssl_certificate /var/ssl/your-site.bundle.crt
ssl_certificate /var/ssl/your-private-key.key

и перезапустите ваш веб-сервер (в нашем случае nginx: sudo systemctl restart nginx)

проверьте это с помощью программы проверки sslshopper, вы должны полностью увидеть зеленые стрелки.

запустил наш эмулятор, и вызовы API прошли.

Измените ваши URL с HTTP на HTTPS;

Обновление до React Native 0.58.5 или выше. У них есть includeSubdomain в их конфигурационных файлах в RN 0.58.5.

ChangeLog

В 0,58,5 руб. Они объявили network_security_config с их серверным доменом. Конфигурация безопасности сети позволяет приложению разрешать трафик открытым текстом из определенного домена. Так что нет необходимости прилагать дополнительные усилия, заявив, android:usesCleartextTraffic="true" в теге приложения вашего файла манифеста. Это будет решено автоматически после обновления версии RN.

Добавь это android:usesCleartextTraffic="true" в свой файл Androidmanifest.xml внутри тега приложения.

<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
...   
<application
    ...
    android:usesCleartextTraffic="true"
    ...>
    ...
</application>

Я сделал все вышеперечисленные ответы, и я пришел с лучшим ответом, я надеюсь, что это может помочь:

В Манифест добавить эти строки:

андроид:networkSecurityConfig="@ XML /network_security_config"

а также

андроид:usesCleartextTraffic="истина"

<application
    android:name=".App.Global"
    android:allowBackup="false"
    android:hardwareAccelerated="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:networkSecurityConfig="@xml/network_security_config"
    android:usesCleartextTraffic="true"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    tools:ignore="GoogleAppIndexingWarning,InnerclassSeparator"
    tools:replace="allowBackup,supportsRtl"
    tools:targetApi="n">

А затем в папке res/xml создайте новый файл с именем network_security_config.xml или любым другим!

И добавьте в него следующие строки:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">alibaba.com</domain>
    </domain-config>
</network-security-config>

Это происходит из-за вашего протокола домена, http не является безопасным.

Убедитесь, что домен указан правильно в вашем .

В моем случае я использовал команду с ionic cordovaкоторый изменил домен.

РЕШЕНИЕ 1

Удалить --external

РЕШЕНИЕ 2

Измените свой домен в network_security_config.xml

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

У меня была такая же проблема в моем простом приложении для просмотра веб-страниц, потому что мой URL-адрес был http://, но когда вы перешли на https://, ошибка была решена.

Один лайнер для решения вашей проблемы. Я предполагаю, что вы сохраните свой URL-адрес в строке myURL. Добавьте эту строку, и все готово. myURL = myURL.replace("http", "https");

Другие вопросы по тегам