Nie można załadować zasobu, ponieważ zasada bezpieczeństwa aplikacji transportu wymaga użycia bezpiecznego połączenia

491

Mam problem z aktualizacją Xcode do wersji 7.0 lub iOS 9.0. Jakoś to zaczęło dawać mi tytułowy błąd

„Nie można załadować zasobu, ponieważ zasada bezpieczeństwa aplikacji transportu wymaga użycia bezpiecznego połączenia”

Metoda usługi internetowej:

-(void)ServiceCall:(NSString*)ServiceName :(NSString *)DataString
{
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    [sessionConfiguration setAllowsCellularAccess:YES];
    [sessionConfiguration setHTTPAdditionalHeaders:@{ @"Accept" : @"application/json" }];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@",ServiceURL]];
    NSLog(@"URl %@%@",url,DataString);
    // Configure the Request
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setValue:[NSString stringWithFormat:@"%@=%@", strSessName, strSessVal] forHTTPHeaderField:@"Cookie"];
    request.HTTPBody = [DataString dataUsingEncoding:NSUTF8StringEncoding];
    request.HTTPMethod = @"Post";

    // post the request and handle response
    NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
                                          {
                                              // Handle the Response
                                              if(error)
                                              {
                                                  NSLog(@"%@",[NSString stringWithFormat:@"Connection failed: %@", [error description]]);

                                                  // Update the View
                                                  dispatch_async(dispatch_get_main_queue(), ^{

                                                      // Hide the Loader
                                                      [MBProgressHUD hideHUDForView:[[UIApplication sharedApplication] delegate].window animated:YES];


                                                  });
                                                  return;
                                              }
                                              NSArray * cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:request.URL];
                                              for (NSHTTPCookie * cookie in cookies)
                                              {
                                                  NSLog(@"%@=%@", cookie.name, cookie.value);
                                                  strSessName=cookie.name;
                                                  strSessVal=cookie.value;

                                              }

                                              NSString *retVal = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}];
[postDataTask resume];

}

Usługa działa poprawnie dla wcześniejszych wersji Xcode i wcześniejszych wersji iOS. Ale kiedy zaktualizowałem Xcode 7.0 do iOS 9.0, zaczęło mi pojawiać się problem, gdy wykonuję połączenie z powyższą metodą usługi internetowej. Błąd, który otrzymuję, to:

Połączenie nie powiodło się: Błąd Domena = NSURLErrorDomain Code = -1022 „Nie można załadować zasobu, ponieważ zasady zabezpieczeń transportu aplikacji wymagają bezpiecznego połączenia”. UserInfo = {NSUnderlyingError = 0x7fada0f31880 {Domena błędu = kCFErrorDomainCFNetwork Code = -1022 "(null)"}, NSErrorFailingURLStringKey = MyServiceURL , NSErrorFailingURLKey = MyServiceURL Zabezpieczenie nie wymaga zastosowania bezpieczeństwa, ponieważ nie można użyć tej metody bezpieczeństwa, ponieważ nie można użyć tej usługi. połączenie.}

Próbowałem następujących pytań i odpowiedzi, ale nie uzyskałem żadnego rezultatu, czy jest jakiś pomysł z wyprzedzeniem, jak mogę usunąć ten błąd wezwania serwisu?

  1. Nie można załadować zasobu to ios9
  2. App Transport Security Xcode 7 beta 6
  3. https://stackoverflow.com/a/32609970
Manab Kumar Mal
źródło
możliwy duplikat App Transport Security Xcode 7 beta 6
AiOsN

Odpowiedzi:

935

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

  1. Otworzyłem info.plistplik docelowy mojego projektu

  2. Dodano klucz o nazwie NSAppTransportSecurityjako Dictionary.

  3. Dodano podklucz o nazwie NSAllowsArbitraryLoadsas Booleani ustaw jego wartość na YESpodobną do następującego obrazu.

wprowadź opis zdjęcia tutaj

Wyczyść projekt i teraz wszystko działa poprawnie, jak wcześniej.

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

EDYCJA: LUB W kodzie źródłowym info.plistpliku możemy dodać, że:

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
        <key>NSExceptionDomains</key>
        <dict>
            <key>yourdomain.com</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
                <false/>
            </dict>
       </dict>
  </dict>
Manab Kumar Mal
źródło
5
Na początku to nie działa. Musisz także dodać klucze w Projekcie> Cel
orafaelreis,
4
Oto pomocna dokumentacja Apple developer.apple.com/library/ios/documentation/General/Reference/…
LargeGlasses
1
@MihirOza: Tak, bezpieczeństwo transportu to nowa funkcja iOS 9.
Dominic K
2
Jeśli nie masz domen wyjątków, po prostu usuń dowolny klucz poniżej NSExceptionDomains. W przeciwnym razie będzie to wyjątek NSAllowArbitraryLoads, aby to odwiedzić, musisz użyć httpsexception
DawnSong
7
Dla Xcode 8,3 / Swift 3 to App Transport Security Settingsi Allow Arbitrary Loadsodpowiednio
Swapna Lekshmanan
279

Należy pamiętać, że użycie NSAllowsArbitraryLoads = truew projekcie info.plistpozwala na niepewne połączenie z dowolnym serwerem. Jeśli chcesz się upewnić, że tylko określona domena jest dostępna przez niepewne połączenie, spróbuj tego:

wprowadź opis zdjęcia tutaj

Lub jako kod źródłowy:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>domain.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>

Wyczyść i zbuduj projekt po edycji.

Arjan
źródło
dzięki za odpowiedź właśnie NSAllowArbitaryLoads nie działało dla mnie dodając NSExceptionAllowsInsecureHTTPLoads załatwiło sprawę
neeta
1
Dodałem również te dwa klucze: <! - Uwzględnij, aby zezwolić na żądania HTTP -> <klucz> NSTemporaryExceptionAllowsInsecureHTTPLoads </key> <true /> <! - Dołącz, aby określić minimalną wersję TLS -> <key> NSTemporaryExceptionMinimumTLSVersion </ key> <string> TLSv1.1 </string> Sprawiło to, że ładuje się również dużo szybciej.
Sandy D.,
Uwaga: Teraz używam XCode 8: Jeśli robisz to ręcznie, kliknij prawym przyciskiem myszy domenę> Typ wartości> Słownik, aby dodać „..AllowsInsecure ...” i „... IncludesSubdomains”
ArielSD
Nie działa, jeśli podam numer portu po domenie.com. (domena.com:3001 na przykład)
Shamsiddin
43

Zabezpieczenia transportu są zapewnione w iOS 9.0 lub nowszym oraz w OS X 10.11 i nowszym.

Tak więc domyślnie dozwolone są tylko połączenia https w aplikacjach. Aby wyłączyć App Transport Security, dodaj następujące wiersze w pliku info.plist ...

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

Aby uzyskać więcej informacji:
https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33

Teja Kumar Bethina
źródło
Ale nadal nie pozwala mi to na wykonywanie połączeń HTTP do żadnej domeny. Czy jest jakaś wskazówka, dlaczego tak się dzieje?
Mrug
Nawet jeśli jest to adres URL HTTP, adres URL powinien zostać skwerfikowany lub powinien mieć certyfikat SSL vlid.
Teja Kumar Bethina
35

Na iOS 10.x i Swift 3.x [obsługiwane są również poniższe wersje] wystarczy dodać następujące wiersze w „info.plist”

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
Pan Fasola
źródło
1
W wersjach 10.x i Swift 3.x widziałem gdzie indziej, że klucze były w rzeczywistości AppTransportSecurity i AllowsArbitraryLoads, ale były one nieprawidłowe. prefiks NS jest nadal potrzebny dla tych kluczy, nawet w Swift 3.x. Błąd zniknął, gdy polegałem na prefiksie NS dla tych kluczy.
Jazzmine
27

W Swift 4 możesz używać

-> Przejdź do Info.plist

-> Kliknij plus listę właściwości informacji

-> Dodaj ustawienia zabezpieczeń transportu aplikacji jako słownik

-> Kliknij ikonę Plus Ustawienia zabezpieczeń transportu aplikacji

-> Dodaj Zezwalaj na obciążenia arbitralne ustaw TAK

Poniższy obraz wygląda

wprowadź opis zdjęcia tutaj

Enamul Haque
źródło
23

Rozwiązałem jako plik plist.

Dodaj NSAppTransportSecurity: Dictionary.

Dodaj podklucz o nazwie „NSAllowsArbitraryLoads” jako wartość logiczną: TAK

wprowadź opis zdjęcia tutaj

Avinash651
źródło
18

Nie można załadować zasobu, ponieważ zasada bezpieczeństwa aplikacji transportu wymaga użycia bezpiecznego połączenia działającego w Swift 4.03.

Otwórz pList.info jako kod źródłowy i wklej:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
Keshav Gera
źródło
13

Z dokumentacji Apple

Jeśli opracowujesz nową aplikację, powinieneś używać wyłącznie HTTPS. Jeśli masz już istniejącą aplikację, powinieneś w tej chwili używać HTTPS i stworzyć plan jak najszybszej migracji reszty aplikacji. Ponadto komunikacja za pośrednictwem interfejsów API wyższego poziomu musi być szyfrowana przy użyciu TLS w wersji 1.2 z zachowaniem tajemnicy przekazywania. Jeśli spróbujesz nawiązać połączenie, które nie spełnia tego wymagania, generowany jest błąd. Jeśli aplikacja musi wysłać żądanie do niezabezpieczonej domeny, musisz określić tę domenę w pliku Info.plist aplikacji.

Aby ominąć zabezpieczenia transportu aplikacji:

<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>

Aby zezwolić na wszystkie niepewne domeny

<key>NSAppTransportSecurity</key>
<dict>
  <!--Include to allow all connections (DANGER)-->
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

Czytaj więcej: Konfigurowanie wyjątków bezpieczeństwa transportu aplikacji w iOS 9 i OSX 10.11

Ashok R.
źródło
11

Jeśli używasz Xcode 8.0 i swift 3.0 lub 2.2

wprowadź opis zdjęcia tutaj

Anit Kumar
źródło
9

W Xcode 7.1 i nowszych (swift 2.0)

wprowadź opis zdjęcia tutaj

AG
źródło
9

W ten sposób Apple wymusza ściślejsze zabezpieczenia api (zmuszony do korzystania z https przez http). Wyjaśnię, jak usunąć to ustawienie bezpieczeństwa.


Większość odpowiedzi tutaj wskazuje na dodanie tego klucza do swojej info.plist wprowadź opis zdjęcia tutaj

Samo to nie rozwiązało dla mnie tego problemu. Musiałem dodać ten sam klucz do środka

Project -> Targets -> Info -> Custom iOS Target Properties wprowadź opis zdjęcia tutaj


Pozwoli to jednak na nawiązanie niezabezpieczonych połączeń od kogokolwiek. Jeśli chcesz zezwolić tylko określonej domenie na używanie niezabezpieczonych połączeń, możesz dodać następujące informacje do swojej info.plist.

wprowadź opis zdjęcia tutaj

Sam
źródło
Dzięki, to zadziałało dla mnie! Edytowałem tylko plik plist, przed którym nie działało. Jestem zaskoczony, jak inni ludzie tak to
działali
8

Wystarczy użyć HTTPS, a nie HTTP w adresie URL, a to zadziała

pierre23
źródło
3
Chyba że oczywiście nie możesz używać HTTPS, ponieważ Apple nie lubi certyfikatów z podpisem własnym. Nie masz tego problemu?
Tony B
1
W moim przypadku działa idealnie, odkąd zmieniłem na HTTPS
pierre23
1
ale czy używasz certyfikatu z podpisem własnym lub z urzędu certyfikacji? Po prostu ciekawy. To oczywiście osobna sprawa, ale pomyślałem, że zapytam.
Tony B
Nie
działałem
Ustanowienie połączenia HTTPS w niektórych środowiskach serwerowych (hosting współdzielony) może być trudne.
Raptor,
7

Jeśli nie jesteś wielkim fanem XML, po prostu dodaj poniższy znacznik w pliku plist.

wprowadź opis zdjęcia tutaj

MrWaqasAhmed
źródło
5

iOS 9 (może) zmusza programistów do korzystania wyłącznie z aplikacji App Transport Security . Słyszałem to gdzieś losowo, więc sam nie wiem, czy to prawda. Ale podejrzewam to i doszedłem do tego wniosku:

Aplikacja działająca na iOS 9 (może) nie będzie już łączyć się z serwerem Meteor bez SSL.

Oznacza to, że uruchomione urządzenie meteor z systemem iOS lub urządzenie z systemem Meteor działa (prawdopodobnie?) Już nie będzie działać.

W info.plist aplikacji NSAppTransportSecurity [Dictionary]musi NSAllowsArbitraryLoads [Boolean]być ustawiony klucz, w przeciwnym razie YESMeteor będzie musiał httpsgo localhost serverwkrótce użyć .

Mahesh
źródło
5

Jeśli używasz Xcode 8.0 do 8.3.3 i szybkich 2.2 do 3.0

W moim przypadku należy zmienić adres URL http: // na https: // (jeśli nie działa, spróbuj)

Add an App Transport Security Setting: Dictionary.
Add a NSAppTransportSecurity: Dictionary.
Add a NSExceptionDomains: Dictionary.
Add a yourdomain.com: Dictionary.  (Ex: stackoverflow.com)

Add Subkey named " NSIncludesSubdomains" as Boolean: YES
Add Subkey named " NSExceptionAllowsInsecureHTTPLoads" as Boolean: YES

wprowadź opis zdjęcia tutaj

Md Imran Choudhury
źródło
3

Otwórz pList.info jako kod źródłowy i na dole tuż przed </dict>dodaniem następującego kodu,

 <!--By Passing-->
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>your.domain.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>
    <!--End Passing-->

I na koniec zmień your.domain.comswój podstawowy adres URL. Dzięki.

Najam
źródło
3

Dla tych z was, którzy rozwijają się na localhost, wykonaj następujące kroki:

  1. Naciśnij przycisk „+” obok, Information Property Lista następnie dodaj App Transport Security Settingsi przypisz mu DictionaryTyp
  2. Naciśnij przycisk „+” obok nowo utworzonego App Transport Security Settingswpisu, dodaj NSExceptionAllowsInsecureHTTPLoadstyp Booleani ustaw jego wartość na YES.
  3. Kliknij NSExceptionAllowsInsecureHTTPLoadswpis prawym przyciskiem myszy i kliknij opcję „Shift Row Right”, aby uczynić go dzieckiem powyższego wpisu.
  4. Naciśnij przycisk „+” obok NSExceptionAllowsInsecureHTTPLoadswpisu, dodaj Allow Arbitrary Loadstyp Booleani ustaw jego wartość naYES

Uwaga: powinno to ostatecznie wyglądać jak na poniższym obrazku

wprowadź opis zdjęcia tutaj

ISS
źródło
2

Udało mi się to rozwiązać za pomocą kombinacji wielu wymienionych opcji. Dołączę listę kontrolną wszystkich rzeczy, które musiałem zrobić, aby to zadziałało.

W skrócie:

  1. Ustawiony NSAllowsArbitraryLoadsna true dla mojego rozszerzenia zegarka (nie dla mojej aplikacji zegarka).
  2. Upewnij się, że używałem httpsi nie http.

Krok pierwszy:

Po pierwsze i oczywiście musiałem dodać NSAppTransportSecurityklucz jako słownik w moim rozszerzeniu zegarka info.plistz podkluczem o nazwie NSAllowsArbitraryLoadsboolean ustawionym na true. Ustaw to tylko w rozszerzeniu zegarka, a nie na liście aplikacji zegarka. Pamiętaj jednak, że pozwala to na wszystkie połączenia i może być niepewne.

wprowadź opis zdjęcia tutaj

lub

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

Krok drugi:

Potem musiałem się upewnić, że adres URL, który próbowałem załadować, był httpsnie tylko http. W przypadku adresów URL, które nadal były http, użyłem:

Szybki :

let newURLString = oldURLString.stringByReplacingOccurrencesOfString("http", withString: "https")

Obj-C:

NSString *newURLString = [oldURLString stringByReplacingOccurrencesOfString:@“http” withString:@“https”];

Gordonium
źródło
2

Upewnij się, że zmienisz właściwy plik info.plist .

Po raz drugi tracę czas na ten problem, ponieważ nie zauważyłem, że zmieniam info.plist w MyProjectNameUITests.

Shefy Gur-ary
źródło
1

Jeśli użyjesz bazy ogniowej, zostanie dodana NSAllowsArbitraryLoadsInWebContent = truew NSAppTransportSecuritysekcji i NSAllowsArbitraryLoads = truenie będzie działać

cn00
źródło
Dzięki za tą informację. Zaoszczędziłeś mi godziny rozwiązywania problemów.
pAkY88
0

Rozwiązałem ten problem w przypadku hostowanego parsowania serwera przy użyciu certyfikatu z rocznym podpisem, a nie opcji „NSAllowsArbitraryLoads”

Przetwarzaj serwer jako dowolny serwer node.js przedstawia publiczny adres URL https , który musisz określić. Na przykład:

parsuj serwer --appId --masterKey --publicServerURL https: //y.p.picic.url/some_nodejs

Zapraszam do przejrzenia moich plików konfiguracyjnych

CyrIng
źródło