Échec du chargement HTTP de NSURLSession / NSURLConnection sur iOS 9


137

J'ai essayé d'exécuter mon application existante sur iOS9 mais j'ai échoué lors de l'utilisation AFURLSessionManager.

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

    } else {

    }
}];

[task resume];

J'obtiens l'erreur suivante:

Error Domain=NSURLErrorDomain Code=-999 "cancelled.

Obtention également des journaux suivants:

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

Mise à jour: j'ai ajouté plusieurs mises à jour à ma solution: le chargement HTTP de NSURLSession / NSURLConnection a échoué sur iOS 9


Vous êtes certain que l'erreur se produit sur la première ligne?
BSMP

1
J'ai eu le même problème. Cela semblait couvrir le problème: stackoverflow.com/questions/30720813/…
phillies2628

Réponses:


240

Solution trouvée:

Dans iOS9, ATS applique les meilleures pratiques lors des appels réseau, y compris l'utilisation de HTTPS.

À partir de la documentation Apple:

ATS empêche la divulgation accidentelle, fournit un comportement par défaut sécurisé et est facile à adopter. Vous devez adopter ATS dès que possible, que vous créiez une nouvelle application ou que vous mettiez à jour une application existante. Si vous développez une nouvelle application, vous devez utiliser HTTPS exclusivement. Si vous avez une application existante, vous devez utiliser HTTPS autant que vous le pouvez dès maintenant et créer un plan pour migrer le reste de votre application dès que possible.

Dans la version bêta 1, il n'y a actuellement aucun moyen de définir cela dans info.plist. La solution est de l'ajouter manuellement:

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

entrez la description de l'image ici

Update1: il s'agit d'une solution de contournement temporaire jusqu'à ce que vous soyez prêt à adopter la prise en charge d'iOS9 ATS.

Update2: Pour plus de détails, veuillez consulter le lien suivant: http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/

Update3: Si vous essayez de vous connecter à un hôte (YOURHOST.COM) qui n'a que TLS 1.0

Ajoutez-les à Info.plist de votre application

<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
Sachez que vous venez de vous débarrasser complètement de Application Transport Security, donc une fonctionnalité majeure d'iOS 9 vient de disparaître de votre application. C'est un hack, et je ne serais pas surpris si ce hack obtiendrait votre ap rejeté. L'ajout de sites Web particuliers à ces dictionnaires sera plus probablement autorisé.
gnasher729

2
@StevenPeterson Vous ne pourrez exclure qu'une application entière au cas par cas par Apple. Je suppose que si Apple bénit votre application avec cette capacité, il vous demandera d'inclure cette clé. Attendez-vous à ce qu'Apple fasse cela rarement.
mattyohe

8
S'il vous plaît, s'il vous plaît, s'il vous plaît, s'il vous plaît, s'il vous plaît - n'ajoutez pas seulement l'exception à votre plist et passez à "juste parce que ça marche". Tenez compte de la sécurité des données de vos utilisateurs et implémentez SSL et d'autres bonnes pratiques de sécurité.
Santa Claus

8
@ gnasher729, je comprends qu'il vaut mieux prendre en charge TLS 1.2, au lieu de simplement désactiver ATS. Cependant, que pouvez-vous faire si vous comptez sur une API / un service Web tiers. Je ne peux pas les forcer à mettre à niveau, alors que puis-je faire
Woodstock

7
Il y a un bogue subtil dans cette réponse: NSTemporaryExceptionMinimumTLSVersiondoit être par exemple TLSv1.0 au lieu de 1.0 , voir NSAppTransportSecurity Exception Domaines de clés de dictionnaire
mbi

54

Comment gérer le SSL dans iOS9 , Une solution consiste à faire comme:

Comme le dit Apple : entrez la description de l'image ici entrez la description de l'image ici

entrez la description de l'image ici

iOS 9 et OSX 10.11 nécessitent SSL TLSv1.2 pour tous les hôtes auxquels vous prévoyez de demander des données, sauf si vous spécifiez des domaines d'exception dans le fichier Info.plist de votre application.

La syntaxe de la configuration Info.plist ressemble à ceci:

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

Si votre application (un navigateur Web tiers, par exemple) doit se connecter à des hôtes arbitraires, vous pouvez la configurer comme suit:

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

Si vous devez le faire, il est probablement préférable de mettre à jour vos serveurs pour qu'ils utilisent TLSv1.2 et SSL, s'ils ne le font pas déjà. Cela doit être considéré comme une solution de contournement temporaire.

À ce jour, la documentation de la version préliminaire ne fait aucune mention d'aucune de ces options de configuration. Une fois cela fait, je mettrai à jour la réponse pour créer un lien vers la documentation pertinente.

Pour plus d'informations, accédez à iOS9AdaptationTips


4
SSL et TLS sont des couches de cryptage différentes utilisées par les protocoles HTTPS. Ainsi, il faut désactiver complètement SSL et utiliser TLS v1.2 ou version ultérieure. Pour plus d'informations, je recommanderais de commencer par la ressource suivante: Sécurité SSL / TLS 2015 - Un guide rapide simplifié
Conrad Taylor

2
Je n'ai ajouté que de la chance avec l'exemple du bas où vous définissez NSAllowsArbitraryLoads sur true. Mon serveur utilise exclusivement TLS v1.2 et je dois encore le faire pour qu'il fonctionne. Très frustrant.
Scooter

1
Alors, y a-t-il une solution de contournement que je pourrais utiliser pour savoir avec certitude que ma nouvelle application sera approuvée dans l'App Store, comme un service proxy?
Josh

41

La technote d'Apple sur la sécurité du transport des applications est très pratique ; cela nous a aidés à trouver une solution plus sûre à notre problème.

J'espère que cela aidera quelqu'un d'autre. Nous avions des problèmes de connexion aux URL Amazon S3 qui semblaient être des URL HTTPS TLSv12 parfaitement valides. Il s'avère que nous avons dû désactiver NSExceptionRequiresForwardSecrecypour activer une autre poignée de chiffrements utilisés par S3.

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

C'était mon problème exact, et il l'a résolu instantanément! Remercier! :)
Alex Zak

Cela résout le problème que j'avais aussi; différents cas peuvent cependant nécessiter des paramètres différents. La bonne nouvelle est que la note technique contient également des informations sur l'utilisation de nsurl pour vous aider à trouver les bons paramètres en général.
écotaxe

J'avais besoin de faire de même pour cloudfront.net si j'utilisais un CDN devant Amazon S3.
Raymond26

7

Si vous rencontrez ce problème avec Amazon S3 comme moi, essayez de le coller sur votre info.plist en tant qu'enfant direct de votre balise de niveau supérieur

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

Vous pouvez trouver plus d'informations sur:

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


2
God bless you bro
Vervatovskis

5

J'ai trouvé une solution d' ici. Et ça marche pour moi.

Vérifiez ceci, cela peut vous aider.

<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

Ajoutez simplement les champs suivants dans votre fichier .plist

entrez la description de l'image ici

La syntaxe ressemble à ceci:

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

Cela permettra toutes les requêtes http. Fonctionne, mais pas recommandé.
KVISH

2

Mettre à jour:

Depuis Xcode 7.1, vous n'avez pas besoin de saisir manuellement le NSAppTransportSecuritydictionnaire dans le fichier info.plist.

Il se complétera maintenant automatiquement pour vous, réalisera qu'il s'agit d'un dictionnaire, puis complétera automatiquement les Allows Arbitrarycharges. Capture d'écran info.plist


Cela permettra toutes les requêtes http. Fonctionne, mais pas recommandé.
KVISH

2

Résoudre le bogue de chargement de NSURLConnection Http a échoué Ajoutez simplement le dicton suivant dans info.plist:

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

1

Je l'ai résolu en ajoutant une clé dans info.plist. Les étapes que j'ai suivies sont:

J'ai ouvert le fichier info.plist de mon projet

Ajout d'une clé appelée NSAppTransportSecurity en tant que dictionnaire.

Ajout d'une sous-clé appelée NSAllowsArbitraryLoads en tant que booléen et définissez sa valeur sur YES comme dans l'image suivante. entrez la description de l'image ici

Nettoyez le projet et maintenant tout fonctionne correctement comme avant.

Lien de référence: https://stackoverflow.com/a/32609970


1

C'est ce qui a fonctionné pour moi lorsque j'ai eu cette erreur:

<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

Vous pouvez essayer d'ajouter cette fonction dans le fichier RCTHTTPRequestHandler.m

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


1

En plus des réponses mentionnées ci-dessus, revérifiez votre URL


Dans mon cas, j'essayais de charger un fichier .html.
Vaishnavi

0

Vous devez ajouter App Transport Security Settingsà info.plistet ajouter Allow Arbitrary LoadsàApp Transport Security Settings

entrez la description de l'image ici

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.