NSURLSession / NSURLConnection HTTP加载在iOS 9上失败


137

试图在iOS9上运行我现有的应用程序,但在使用时出现故障AFURLSessionManager

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

    } else {

    }
}];

[task resume];

我收到以下错误:

Error Domain=NSURLErrorDomain Code=-999 "cancelled.

还获得以下日志:

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

更新: 我为解决方案添加了多个更新: NSURLSession / NSURLConnection在iOS 9上的HTTP加载失败


您确定错误发生在第一行吗?
BSMP 2015年

1
我遇到过同样的问题。这似乎覆盖问题:stackoverflow.com/questions/30720813/...
phillies2628

Answers:


240

找到的解决方案:

在iOS9中,ATS会在网络通话期间实施最佳做法,包括使用HTTPS。

从Apple文档中:

ATS可以防止意外泄露,提供安全的默认行为,并且易于采用。无论是创建新应用还是更新现有应用,您都应尽快采用ATS。如果要开发新的应用程序,则应专门使用HTTPS。如果您已经有一个应用程序,则应立即使用HTTPS,并制定一个计划,以尽快迁移其余应用程序。

在beta 1中,当前无法在info.plist中定义它。解决方案是手动添加:

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

在此处输入图片说明

Update1:这是一个临时解决方法,直到您准备采用iOS9 ATS支持。

Update2:有关更多详细信息,请参阅以下链接:http : //ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/

Update3:如果您尝试连接到仅具有TLS 1.0的主机(YOURHOST.COM)

将它们添加到您应用的Info.plist

<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
请注意,您刚刚完全摆脱了应用程序传输安全性,因此应用程序中只有一项主要的iOS 9功能。这是一个hack,如果该hack被您的ap拒绝,我不会感到惊讶。将特定网站添加到该词典中的可能性更高。
gnasher729

2
@StevenPeterson您只能逐个案例获取Apple逐个排除的整个应用程序。我认为如果Apple祝福您的应用具有此功能,他们会指示您包括此密钥。期望苹果很少这样做。
mattyohe

8
拜托,拜托,拜托,拜托,拜托 -不要只将例外添加到您的plist中,而继续进行“仅因为它起作用”。考虑用户数据的安全性,并实施SSL和其他安全性最佳做法。
2015年

8
@ gnasher729,我知道最好支持TLS 1.2,而不仅仅是禁用ATS。但是,如果您依赖第三方API / Web服务,该怎么办。我不能强迫他们升级,该怎么办?
Woodstock 2015年

7
此答案中有一个细微的错误:NSTemporaryExceptionMinimumTLSVersion必须为TLSv1.0而不是1.0,请参见NSAppTransportSecurity 异常域字典键
mbi

54

如何在iOS9中处理SSL,一种解决方案是:

正如苹果所说: 在此处输入图片说明 在此处输入图片说明

在此处输入图片说明

除非您在应用的Info.plist文件中指定例外域,否则iOS 9和OSX 10.11要求您计划向其请求数据的所有主机使用TLSv1.2 SSL。

Info.plist配置的语法如下所示:

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

如果您的应用程序(例如第三方Web浏览器)需要连接到任意主机,则可以按以下方式进行配置:

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

如果必须这样做,最好将服务器更新为使用TLSv1.2和SSL(如果尚未这样做)。这应被视为临时解决方法。

到目前为止,预发行版文档没有以任何特定方式提及任何这些配置选项。完成后,我将更新答案以链接到相关文档。

有关更多信息,请转到iOS9AdaptationTips


4
SSL和TLS是HTTPS协议使用的不同加密层。因此,应该完全禁用SSL并使用TLS v1.2或更高版本。有关更多信息,我建议从以下资源开始:SSL / TLS Security 2015-简化快速指南
Conrad Taylor

2
我只在下面的示例中添加了运气,您将NSAllowsArbitraryLoads设置为true。我的服务器仅使用TLS v1.2,我仍然必须这样做才能使其正常工作。非常沮丧。
滑板车

1
那么,有什么变通办法可以用来确定我的新应用将在App Store中获得批准,例如代理服务吗?
乔什

41

苹果公司关于应用程序传输安全性的技术说明非常方便;它帮助我们找到了更安全的解决方案。

希望这会帮助其他人。我们在连接到看上去完全有效的Amazon S3 URL(TLSv12 HTTPS URL)时遇到问题。事实证明,我们必须禁用NSExceptionRequiresForwardSecrecy才能启用S3使用的其他少数密码。

在我们的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>

这是我的确切问题,可以立即解决!谢谢!:)
Alex Zak 2015年

这也解决了我遇到的问题;不同的情况可能需要不同的设置。好消息是,他的技术说明中还包含有关如何使用nsurl帮助您总体上找到正确设置的信息。
ecotax 2015年

如果在Amazon S3之前使用CDN,则需要对cloudfront.net进行相同的操作。
雷蒙德2015年

7

如果您像我那样遇到Amazon S3的问题,请尝试将其作为顶级标签的直接子项粘贴到info.plist上

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

您可以在以下位置找到更多信息:

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


2
上帝保佑你的兄弟
Vervatovskis

5

我从这里找到了解决方案 它为我工作。

对此进行检查,可能会对您有所帮助。

<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

只需在.plist文件中添加以下字段

在此处输入图片说明

语法如下:

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

这将允许所有http请求。可行,但不推荐。
KVISH

2

更新:

从Xcode 7.1开始,您无需在中手动输入NSAppTransportSecurityDictionary info.plist

现在它将为您自动完成,意识到它是字典,然后也自动完成Allows Arbitrary负载。 info.plist屏幕截图


这将允许所有http请求。可行,但不推荐。
KVISH '16

2

解决NSURLConnection Http加载失败的bug只需在info.plist中添加以下Dict:

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

1

我已经通过在info.plist中添加一些键解决了它。我遵循的步骤是:

我打开了项目的info.plist文件

添加了一个名为NSAppTransportSecurity的密钥作为字典。

添加了一个名为NSAllowsArbitraryLoads的子项作为布尔值,并将其值设置为YES,如下图所示。在此处输入图片说明

清理项目,现在一切都像以前一样运行良好。

参考链接:https : //stackoverflow.com/a/32609970


1

当我遇到此错误时,这对我有用:

<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

您可以尝试在文件RCTHTTPRequestHandler.m中添加此功能。

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



0

您应该添加App Transport Security Settingsinfo.plist并添加Allow Arbitrary LoadsApp Transport Security Settings

在此处输入图片说明

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.