NSURLSession / NSURLConnection La carga HTTP falló en iOS 9

137

Intenté ejecutar mi aplicación existente en iOS9 pero recibí un error mientras lo usaba AFURLSessionManager.

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

    } else {

    }
}];

[task resume];

Obtuve el siguiente error:

Error Domain=NSURLErrorDomain Code=-999 "cancelled.

También obteniendo los siguientes registros:

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

Actualización: he agregado varias actualizaciones a mi solución: NSURLSession / NSURLConnection La carga HTTP falló en iOS 9

Tariq
fuente
¿Estás seguro de que el error está sucediendo en la primera línea?
BSMP
1
Tuve el mismo problema. Esto pareció cubrir el problema: stackoverflow.com/questions/30720813/…
phillies2628

Respuestas:

240

Solución encontrada:

En iOS9, ATS aplica las mejores prácticas durante las llamadas de red, incluido el uso de HTTPS.

De la documentación de Apple:

ATS evita la divulgación accidental, proporciona un comportamiento predeterminado seguro y es fácil de adoptar. Debe adoptar ATS lo antes posible, independientemente de si está creando una nueva aplicación o actualizando una existente. Si está desarrollando una nueva aplicación, debe usar HTTPS exclusivamente. Si tiene una aplicación existente, debe usar HTTPS tanto como pueda en este momento y crear un plan para migrar el resto de su aplicación lo antes posible.

En la versión beta 1, actualmente no hay forma de definir esto en info.plist. La solución es agregarlo manualmente:

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

ingrese la descripción de la imagen aquí

Actualización1: Esta es una solución temporal hasta que esté listo para adoptar el soporte ATS iOS9.

Actualización2: Para más detalles, consulte el siguiente enlace: http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/

Actualización3: si está intentando conectarse a un host (YOURHOST.COM) que solo tiene TLS 1.0

Agréguelos a la lista de información de su aplicación

<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>
Tariq
fuente
10
Tenga en cuenta que acaba de deshacerse de Application Transport Security por completo, por lo que una de las principales funciones de iOS 9 acaba de desaparecer de su aplicación. Este es un hack, y no me sorprendería si ese hack hiciera que tu ap sea rechazada. Es más probable que se agreguen sitios web particulares a estos diccionarios.
gnasher729
2
@StevenPeterson Solo podrá obtener una aplicación completa excluida caso por caso por Apple. Supongo que si Apple bendice tu aplicación con esta capacidad, te indicará que incluyas esta clave. Espere que Apple haga esto raramente.
mattyohe
8
Por favor, por favor, por favor, por favor , no solo agregue la excepción a su lista y continúe "simplemente porque funciona". Considere la seguridad de los datos de su usuario e implemente SSL y otras mejores prácticas de seguridad.
Santa Claus
8
@ gnasher729, entiendo que es mejor admitir TLS 1.2, en lugar de deshabilitar ATS. Sin embargo, ¿qué puede hacer si confía en un servicio web / API de terceros? No puedo obligarlos a actualizar, ¿qué puedo hacer?
Woodstock
77
Hay un error sutil en esta respuesta: NSTemporaryExceptionMinimumTLSVersiondebe ser, por ejemplo, TLSv1.0 en lugar de 1.0 , consulte las claves del diccionario de dominios de excepción
mbi
54

Cómo lidiar con el SSL en iOS9, una solución es hacer lo siguiente:

Como dice la manzana : ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

iOS 9 y OSX 10.11 requieren SSL TLSv1.2 para todos los hosts de los que planea solicitar datos, a menos que especifique dominios de excepción en el archivo Info.plist de su aplicación.

La sintaxis para la configuración de Info.plist se ve así:

<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 su aplicación (un navegador web de terceros, por ejemplo) necesita conectarse a hosts arbitrarios, puede configurarla así:

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

Si tiene que hacer esto, probablemente sea mejor actualizar sus servidores para usar TLSv1.2 y SSL, si aún no lo están haciendo. Esto debe considerarse una solución temporal.

A partir de hoy, la documentación preliminar no menciona ninguna de estas opciones de configuración de manera específica. Una vez que lo haga, actualizaré la respuesta para vincular a la documentación relevante.

Para obtener más información, vaya a iOS9AdaptationTips

ElonChan
fuente
44
SSL y TLS son diferentes capas de cifrado utilizadas por los protocolos HTTPS. Por lo tanto, uno debe deshabilitar SSL por completo y usar TLS v1.2 o posterior. Para obtener más información, recomendaría comenzar con el siguiente recurso: SSL / TLS Security 2015 - Una guía rápida simplificada
Conrad Taylor
2
Solo agregué suerte con el ejemplo inferior en el que estableces NSAllowsArbitraryLoads en verdadero. Mi servidor está usando TLS v1.2 exclusivamente y todavía tengo que hacer esto para que funcione. Muy frustrante.
Scooter
1
Entonces, ¿hay alguna solución alternativa que pueda usar para saber con certeza si mi nueva aplicación será aprobada en la App Store, como un servicio proxy?
Josh
41

La nota técnica de Apple sobre seguridad en el transporte de aplicaciones es muy útil ; nos ayudó a encontrar una solución más segura para nuestro problema.

Esperemos que esto ayude a alguien más. Estábamos teniendo problemas para conectarnos a las URL de Amazon S3 que parecían ser perfectamente válidas, las URL TLSv12 HTTPS. Resulta que tuvimos que deshabilitar NSExceptionRequiresForwardSecrecypara habilitar otro puñado de cifrados que usa S3.

En nuestro 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>
Ben Kreeger
fuente
Este fue mi problema exacto, ¡y lo solucionó al instante! ¡Gracias! :)
Alex Zak
Esto resuelve el problema que tuve también; Sin embargo, diferentes casos pueden requerir diferentes configuraciones. La buena noticia es que la nota técnica también contiene información sobre cómo usar nsurl para ayudarlo a encontrar la configuración correcta en general.
ecotax
Necesitaba hacer lo mismo para cloudfront.net si usaba un CDN frente a Amazon S3.
Raymond26
7

Si tiene este problema con Amazon S3 como yo, intente pegar esto en su info.plist como hijo directo de su etiqueta de nivel superior

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

Puedes encontrar más información en:

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

David Cespedes
fuente
2
Dios te bendiga hermano
Vervatovskis
5

Encontré una solución desde aquí. Y está funcionando para mí.

Mira esto, puede ayudarte.

<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>
Ashvin Ajadiya
fuente
4

Simplemente agregue los siguientes campos en su archivo .plist

ingrese la descripción de la imagen aquí

La sintaxis se ve así:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
geet Sebastian
fuente
Esto permitirá todas las solicitudes http. Funciona, pero no recomendado.
KVISH
2

Actualizar:

A partir de Xcode 7.1, no necesita ingresar manualmente el NSAppTransportSecurityDiccionario en elinfo.plist .

Ahora se completará automáticamente para usted, se dará cuenta de que es un diccionario y luego también completará automáticamente las Allows Arbitrarycargas. captura de pantalla de info.plist

Ben
fuente
Esto permitirá todas las solicitudes http. Funciona, pero no recomendado.
KVISH
2

Solucione el error de carga fallida NSURLConnection Http Solo agregue el siguiente Dict en info.plist:

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
        <key>NSAllowsArbitraryLoadsInWebContent</key>
        <true/>
    </dict>
Sakir Sherasiya
fuente
1

Lo resolví agregando algunas claves en info.plist. Los pasos que seguí son:

Abrí el archivo info.plist de mi proyecto

Se agregó una clave llamada NSAppTransportSecurity como diccionario.

Se agregó una subclave llamada NSAllowsArbitraryLoads como booleana y estableció su valor en SÍ como en la siguiente imagen. ingrese la descripción de la imagen aquí

Limpia el proyecto y ahora todo funciona bien como antes.

Enlace de referencia: https://stackoverflow.com/a/32609970

tania_S
fuente
1

Esto es lo que funcionó para mí cuando tuve este error:

<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>
KVISH
fuente
1

Puede intentar agregar esta función en el archivo RCTHTTPRequestHandler.m

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

eliprodigy
fuente
1

Además de las respuestas mencionadas anteriormente, vuelva a verificar su URL

Vaishnavi
fuente
En mi caso, estaba tratando de cargar el archivo .html.
Vaishnavi
0

Usted debe agregar App Transport Security Settingsa info.plisty añadir Allow Arbitrary LoadsaApp Transport Security Settings

ingrese la descripción de la imagen aquí

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