NSAppTransportSecurity: не работает с правильными настройками

Как и многие разработчики, я получаю некоторые данные с веб-сервера через http. Начиная с XCOde7/iOS9 мне нужно пометить используемые домены как исключение в списке приложений. Это сработало для всех моих доменов, кроме одного.

Важно: я не могу принять все домены с NSAllowsArbitraryLoads. Сначала я попробовал следующие записи в листе:

<key>cc.mydomain.de</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>

Эта конфигурация работала для всех других доменов, но не для этого, поэтому я добавил следующие записи в plist:

<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
     <false/>
<key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
     <true/>
<key>NSExceptionRequiresForwardSecrecy</key>
    <false/>

Но я все еще получил ошибку при попытке получить доступ к домену.

App Transport Security заблокировала загрузку ресурсов HTTP (http://) открытым текстом, поскольку она небезопасна. Временные исключения могут быть настроены через файл Info.plist вашего приложения

Если эти записи исключений не работают, то что работает? Какая минимальная конфигурация для такого исключения. Какую запись я пропускаю?

4 ответа

Решение

Я связался со службой поддержки Apple Developer по этой проблеме, и они сказали мне, что проблема в том, что один из моих URL-адресов перенаправляет на другой URL-адрес, который, конечно же, также должен быть указан как исключение в моем списке. Вы можете легко определить перенаправление с помощью метода делегата сеанса URL для перенаправления:

self.session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: self, delegateQueue: NSOperationQueue.mainQueue())

let url = NSURL(string: "yoururl")!

self.session.dataTaskWithURL(url) { (data, response, error) in
    if let error = error {
        NSLog("error %@ / %d", error.domain, error.code)
    } else if let response = response as? NSHTTPURLResponse {
        NSLog("response %d", response.statusCode)
    } else {
        fatalError()
    }
}.resume()

func URLSession(session: NSURLSession, task: NSURLSessionTask, willPerformHTTPRedirection response: NSHTTPURLResponse, newRequest request: NSURLRequest, completionHandler: (NSURLRequest?) -> Void) {
        NSLog("direct to %@", request.URL!)
        completionHandler(request)
}

Версия Swift 3:

class ViewController: UIViewController, URLSessionTaskDelegate {

    var session: URLSession! = nil

    override func viewDidLoad() {
         super.viewDidLoad()

         self.session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main)

         let url = NSURL(string: "yoururl")!

         self.session.dataTask(with: url as URL) { (data, response, error) in
             if let error = error {
                 NSLog("error %@ / %d", (error as NSError).domain, (error as NSError).code)
             } else if let response = response as? HTTPURLResponse {
                 NSLog("response %d", response.statusCode)
             } else {
                 fatalError()
             }
             }.resume()
     }

     func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
         print("direct to %@", request.url!)
         completionHandler(request)
     }
}

Попробуй это:

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <!-- .......................... -->
    <!-- Other keys already present -->
    <!-- .......................... -->

    <key>NSAppTransportSecurity</key>
    <dict>

        <key>NSExceptionDomains</key>
        <dict> 

            <key>mydomain.de</key>
            <dict>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSIncludesSubdomains</key>
                <true/>
            </dict>

        </dict>
    </dict>

</dict>
</plist>

Чтобы получить доступ к ресурсу с http://, вам нужно добавить следующие строки в info.plist файл

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

Я добавил App Transport Security Settings, но ошибка все еще появлялась в консоли.

Мое приложение показывало эту ошибку при запуске веб-адреса в UIWebView, Если на вашей странице есть какой-то внутренний URL / фрейм, который добавляется к вашему info.plist как Exception Domains тогда ошибка появится в консоли.

В моем случае я звонил на веб-страницу в UIWebView и на этой странице был плагин facebook. Эта веб-страница загружалась правильно, но эта ошибка также отображалась в консоли. Когда я тщательно проверил, я обнаружил, что в своем приложении я использовал логин Facebook и для этого урока Facebook дал мне указание добавить facebook.com как Exception Domains в info.plist,

введите описание изображения здесь

Когда я удалил это Exception Domainsошибка пропала.

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