Ładowanie HTTP NSURLSession / NSURLConnection nie powiodło się w systemie iOS 9


137

Próbowałem uruchomić moją istniejącą aplikację na iOS9, ale nie udało mi się uruchomić AFURLSessionManager.

__block NSURLSessionDataTask *task = [self.sessionManager dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
    if (error) {

    } else {

    }
}];

[task resume];

Otrzymuję następujący błąd:

Error Domain=NSURLErrorDomain Code=-999 "cancelled.

Otrzymuję również następujące dzienniki:

 NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824
 CFNetwork SSLHandshake failed (-9824)

Aktualizacja: Dodałem wiele aktualizacji do mojego rozwiązania: ładowanie HTTP NSURLSession / NSURLConnection nie powiodło się w systemie iOS 9


Jesteś pewien, że błąd występuje w pierwszej linii?
BSMP

1
Miałem ten sam problem. Wydawało się, że to
rozwiązuje

Odpowiedzi:


240

Znalezione rozwiązanie:

W iOS9 ATS wymusza najlepsze praktyki podczas połączeń sieciowych, w tym użycie HTTPS.

Z dokumentacji Apple:

ATS zapobiega przypadkowemu ujawnieniu, zapewnia bezpieczne zachowanie domyślne i jest łatwy do zastosowania. Powinieneś wdrożyć ATS tak szybko, jak to możliwe, niezależnie od tego, czy tworzysz nową aplikację, czy aktualizujesz istniejącą. Jeśli tworzysz nową aplikację, powinieneś używać wyłącznie protokołu HTTPS. Jeśli masz już istniejącą aplikację, powinieneś używać protokołu HTTPS tak często, jak to możliwe w tej chwili, i jak najszybciej utwórz plan migracji reszty aplikacji.

W wersji beta 1 obecnie nie ma możliwości zdefiniowania tego w info.plist. Rozwiązaniem jest dodanie go ręcznie:

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

wprowadź opis obrazu tutaj

Aktualizacja 1: jest to tymczasowe obejście, dopóki nie będziesz gotowy do przyjęcia obsługi ATS systemu iOS9.

Aktualizacja 2: Aby uzyskać więcej informacji, zapoznaj się z następującym linkiem: http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/

Aktualizacja3: Jeśli próbujesz połączyć się z hostem (YOURHOST.COM), który ma tylko protokół TLS 1.0

Dodaj je do Info.plist swojej aplikacji

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>YOURHOST.COM</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSTemporaryExceptionMinimumTLSVersion</key>
            <string>1.0</string>
            <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
    </dict>
</dict>

10
Pamiętaj, że właśnie całkowicie pozbyłeś się Application Transport Security, więc jedna główna funkcja iOS 9 została usunięta z Twojej aplikacji. To hack i nie zdziwiłbym się, gdyby ten hack spowodował odrzucenie apki. Bardziej prawdopodobne będzie dodanie określonych witryn do tych słowników.
gnasher729

2
@StevenPeterson Będziesz w stanie uzyskać tylko pełną aplikację wykluczoną indywidualnie dla każdego przypadku przez Apple. Zakładam, że jeśli Apple pobłogosławi Twoją aplikację tą możliwością, poinstruuje Cię o dołączeniu tego klucza. Spodziewaj się, że Apple będzie to robić rzadko.
mattyohe

8
Proszę, proszę, proszę, proszę - nie dodawaj wyjątku do swojej listy i przejdź dalej „tylko dlatego, że działa”. Weź pod uwagę bezpieczeństwo danych użytkownika i zastosuj SSL oraz inne sprawdzone metody bezpieczeństwa.
Święty Mikołaj

8
@ gnasher729, rozumiem, że lepiej jest obsługiwać TLS 1.2, zamiast po prostu wyłączać ATS. Co jednak możesz zrobić, jeśli polegasz na zewnętrznym interfejsie API / usłudze sieciowej. Nie mogę zmusić ich do aktualizacji, więc co mogę zrobić?
Woodstock

7
W tej odpowiedzi jest subtelny błąd: NSTemporaryExceptionMinimumTLSVersionmusi to być np. TLSv1.0 zamiast 1.0 , patrz NSAppTransportSecurity Exception klucze słownika domen
mbi

54

Jak radzić sobie z SSL w iOS9 , Jednym z rozwiązań jest:

Jak mówi Apple : wprowadź opis obrazu tutaj wprowadź opis obrazu tutaj

wprowadź opis obrazu tutaj

iOS 9 i OSX 10.11 wymagają TLSv1.2 SSL dla wszystkich hostów, od których planujesz żądać danych, chyba że określisz domeny wyjątków w pliku Info.plist swojej aplikacji.

Składnia konfiguracji Info.plist wygląda następująco:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>yourserver.com</key>
    <dict>
      <!--Include to allow subdomains-->
      <key>NSIncludesSubdomains</key>
      <true/>
      <!--Include to allow insecure HTTP requests-->
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
      <true/>
      <!--Include to specify minimum TLS version-->
      <key>NSTemporaryExceptionMinimumTLSVersion</key>
      <string>TLSv1.1</string>
    </dict>
  </dict>
</dict>

Jeśli Twoja aplikacja (na przykład przeglądarka internetowa innej firmy) musi łączyć się z dowolnymi hostami, możesz to skonfigurować w następujący sposób:

<key>NSAppTransportSecurity</key>
<dict>
    <!--Connect to anything (this is probably BAD)-->
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

Jeśli musisz to zrobić, prawdopodobnie najlepiej zaktualizuj swoje serwery, aby korzystały z TLSv1.2 i SSL, jeśli jeszcze tego nie robią. Należy to uznać za tymczasowe obejście.

Na dzień dzisiejszy dokumentacja wstępna nie wspomina w żaden konkretny sposób o żadnej z tych opcji konfiguracyjnych. Gdy to nastąpi, zaktualizuję odpowiedź tak, aby zawierała link do odpowiedniej dokumentacji.

Aby uzyskać więcej informacji, przejdź do iOS9 AdaptationTips


4
SSL i TLS to różne warstwy szyfrowania używane przez protokoły HTTPS. Dlatego należy całkowicie wyłączyć SSL i używać protokołu TLS w wersji 1.2 lub nowszej. Aby uzyskać więcej informacji, polecam zacząć od następującego źródła: SSL / TLS Security 2015 - uproszczony krótki przewodnik
Conrad Taylor

2
Mam tylko trochę szczęścia z dolnym przykładem, w którym ustawiasz NSAllowsArbitraryLoads na true. Mój serwer używa wyłącznie protokołu TLS v1.2 i nadal muszę to zrobić, aby działał. Bardzo frustrujące.
Scooter

1
Czy jest więc jakieś obejście, którego mógłbym użyć, aby upewnić się, że moja nowa aplikacja zostanie zatwierdzona w App Store, na przykład usługa proxy?
Josh

41

Technote Apple na temat bezpieczeństwa transportu aplikacji jest bardzo przydatny ; pomogło nam to znaleźć bezpieczniejsze rozwiązanie naszego problemu.

Mam nadzieję, że pomoże to komuś innemu. Mieliśmy problemy z łączeniem się z adresami URL Amazon S3, które wydawały się całkowicie prawidłowe, adresami URL TLSv12 HTTPS. Okazało się, że musieliśmy wyłączyć, NSExceptionRequiresForwardSecrecyaby włączyć kolejną garść szyfrów używanych przez S3.

W naszym Info.plist:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>amazonaws.com</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSExceptionRequiresForwardSecrecy</key>
      <false/>
    </dict>
  </dict>
</dict>

To był mój dokładny problem i natychmiast go naprawił! Podziękować! :)
Alex Zak

To rozwiązuje również problem, który miałem; różne przypadki mogą jednak wymagać innych ustawień. Dobrą wiadomością jest to, że notatka techniczna zawiera również informacje o tym, jak używać nsurl, aby ogólnie znaleźć prawidłowe ustawienia.
ekotax

Musiałem zrobić to samo dla cloudfront.net, jeśli korzystałem z CDN przed Amazon S3.
Raymond26

7

Jeśli masz ten problem z Amazon S3 tak jak ja, spróbuj wkleić go na swojej liście info.pl jako bezpośrednie dziecko twojego tagu najwyższego poziomu

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>amazonaws.com</key>
        <dict>
              <key>NSThirdPartyExceptionMinimumTLSVersion</key>
              <string>TLSv1.0</string>
              <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
              <false/>
              <key>NSIncludesSubdomains</key>
              <true/>
        </dict>
        <key>amazonaws.com.cn</key>
        <dict>
              <key>NSThirdPartyExceptionMinimumTLSVersion</key>
              <string>TLSv1.0</string>
              <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
              <false/>
              <key>NSIncludesSubdomains</key>
              <true/>
        </dict>
    </dict>
</dict>

Więcej informacji można znaleźć pod adresem:

http://docs.aws.amazon.com/mobile/sdkforios/developerguide/ats.html#resolving-the-issue


2
Niech cię Bóg błogosławi bracie
Vervatovskis

5

Znalazłem rozwiązanie stąd. I to działa dla mnie.

Sprawdź to, może ci to pomóc.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
         <dict>
             <key>myDomain.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>

4

Po prostu dodaj następujące pola do pliku .plist

wprowadź opis obrazu tutaj

Składnia wygląda następująco:

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

Pozwoli to na wszystkie żądania http. Działa, ale nie jest zalecane.
KVISH

2

Aktualizacja:

Począwszy od Xcode 7.1, nie trzeba ręcznie wprowadzać NSAppTransportSecuritysłownika winfo.plist .

Będzie teraz automatycznie uzupełniany, uświadamia sobie, że jest to słownik, a następnie automatycznie uzupełni również Allows Arbitraryobciążenia. zrzut ekranu info.plist


Pozwoli to na wszystkie żądania http. Działa, ale nie jest zalecane.
KVISH

2

Rozwiąż błąd NSURLConnection Http ładowanie nie powiodło się Po prostu dodaj następujący Dict w info.plist:

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

1

Rozwiązałem to dodając jakiś klucz w info.plist. Kroki, które podjąłem to:

Otworzyłem plik info.plist mojego projektu

Dodano klucz o nazwie NSAppTransportSecurity jako słownik.

Dodano podklucz o nazwie NSAllowsArbitraryLoads jako Boolean i ustaw jego wartość na TAK, jak na poniższym obrazku. wprowadź opis obrazu tutaj

Wyczyść projekt i teraz wszystko działa dobrze, jak poprzednio.

Link referencyjny: https://stackoverflow.com/a/32609970


1

Oto, co zadziałało, gdy miałem ten błąd:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>example.com</key>
        <dict>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSTemporaryExceptionMinimumTLSVersion</key>
            <string>TLSv1.0</string>
        </dict>
    </dict>
</dict>

1

Możesz spróbować dodać tę funkcję w pliku RCTHTTPRequestHandler.m

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); }


1

Oprócz wyżej wymienionych odpowiedzi sprawdź ponownie swój adres URL


W moim przypadku próbowałem załadować plik .html.
Vaishnavi

0

Należy dodać App Transport Security Settings, aby info.plistdodać Allow Arbitrary LoadsdoApp Transport Security Settings

wprowadź opis obrazu tutaj

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.