Как загрузить URL-адрес HTTP с включенной App Transport Security в iOS 9?
Итак, новая бета-версия iOS, выпущенная вчера вечером, имеет "App Transport Security", которая поощряет разработчиков использовать https вместо http. В принципе, это отличная идея, и я уже использую https в нашей рабочей среде. Однако у меня не настроен https в локальной среде разработки, когда приложение iOS подключается к веб-службе, которую я использую на своем ноутбуке.
После небольшой игры сегодня утром кажется, что система загрузки URL-адресов, даже если вы передадите ей URL-адрес http, решит вместо этого использовать https. Кто-нибудь знает, как отключить это поведение - даже только для определенных URL-адресов?
8 ответов
См. Справку Apple Info.plist для получения полной информации (спасибо @gnasher729).
Вы можете добавить исключения для определенных доменов в свой Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>testdomain.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
<false/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSRequiresCertificateTransparency</key>
<false/>
</dict>
</dict>
</dict>
Все ключи для каждого освобожденного домена являются необязательными. Оратор не уточнил ни одну из клавиш, но я думаю, что все они достаточно очевидны.
(Источник: WWDC 2015, сессия 703, "Конфиденциальность и ваше приложение", 30:18)
Вы также можете игнорировать все ограничения безопасности транспорта приложения одним ключом, если у вашего приложения есть веская причина для этого:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Если у вашего приложения нет веской причины, вы можете рискнуть отказаться:
Если установить для NSAllowsArbitraryLoads значение true, это сработает, но Apple ясно дала понять, что намерена отклонить приложения, использующие этот флаг, без особой причины. Основной причиной использования NSAllowsArbitraryLoads, о которой я могу подумать, является созданный пользователем контент (обмен ссылками, пользовательский веб-браузер и т. Д.). И в этом случае Apple по-прежнему ожидает, что вы включите исключения, которые приводят в действие ATS для URL-адресов, которые вы контролируете.
Если вам нужен доступ к определенным URL-адресам, которые не обслуживаются по протоколу TLS 1.2, вам нужно написать конкретные исключения для этих доменов, а не использовать NSAllowsArbitraryLoads со значением yes. Вы можете найти больше информации в сеансе NSURLSesssion WWDC.
Пожалуйста, будьте осторожны, разделяя решение NSAllowsArbitraryLoads. Это не рекомендуемое исправление от Apple.
- Кчарвуд (спасибо @ Марко-Толман)
Поскольку принятый ответ предоставил необходимую информацию, а для получения дополнительной информации об использовании и отключении App Transport Security можно найти больше информации по этому вопросу.
Для исключений по доменам добавьте их в Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>yourserver.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Include to allow HTTP requests-->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--Include to specify minimum TLS version-->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
Но что, если я не знаю всех незащищенных доменов, которые мне нужны? Используйте следующий ключ в вашем Info.plist
<key>NSAppTransportSecurity</key>
<dict>
<!--Include to allow all connections (DANGER)-->
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Последовал за этим.
Я решил это с добавлением ключа в info.plist. Шаги, которые я выполнил:
Открыл мои проекты
info.plist
файлДобавлен ключ под названием
NSAppTransportSecurity
какDictionary
,- Добавлен подраздел с именем
NSAllowsArbitraryLoads
какBoolean
и установите его значениеYES
как на следующем изображении.
Очистите проект, и теперь все работает как обычно.
Если вы просто хотите отключить Политику транспорта приложений для локальных серверов разработки, тогда хорошо подойдут следующие решения. Это полезно, когда вы не можете или не можете настроить HTTPS (например, при использовании сервера разработки Google App Engine).
Однако, как уже говорили другие, ATP определенно не следует отключать для производственных приложений.
1) Используйте другой список для отладки
Скопируйте ваш файл Plist и NSAllowsArbitraryLoads. Используйте этот Plist для отладки.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
2) Исключить локальные серверы
Кроме того, вы можете использовать один файл plist и исключить определенные серверы. Однако не похоже, что вы можете исключить IP-адреса 4, поэтому вам может потребоваться вместо этого использовать имя сервера (находится в Системных настройках -> Общий доступ или настроено в локальном DNS).
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>server.local</key>
<dict/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
Я решил как файл plist.
- Добавьте NSAppTransportSecurity: словарь.
- Добавить подраздел с именем " NSAllowsArbitraryLoads " в качестве логического значения: ДА
Указанные выше конфигурации не работают для меня. Я перепробовал много комбинаций клавиш, эта работает нормально:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>mydomain.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
Компиляция ответов, данных @adurdin и @User
Добавьте следующие данные в ваш info.plist и измените localhost.com
с соответствующим доменным именем вы также можете добавить несколько доменов:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>localhost.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<false/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<false/>
<key>NSExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
<false/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSRequiresCertificateTransparency</key>
<false/>
</dict>
</dict>
</dict>
</plist>
Ваш info.plist должен выглядеть так:
Вот что сработало для меня:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSExceptionDomains</key>
<dict>
<key><!-- your_remote_server.com / localhost --></key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<true/>
</dict>
<!-- add more domain here -->
</dict>
</dict>
Я просто хочу добавить это, чтобы помочь другим и сэкономить время:
если вы используете: CFStreamCreatePairWithSocketToHost
, убедитесь, что ваш host
то же самое с тем, что у вас есть в вашем .plist
или если у вас есть отдельный домен для сокета, просто добавьте его туда.
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)/*from .plist*/, (unsigned int)port, &readStream, &writeStream);
Надеюсь, это полезно. Приветствия.:)