子域上的NSURLSession / NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9802)?

时间:2015-10-19 23:51:23

标签: ios swift ios9

我们的应用程序在我们的生产和开发环境中都运行良好,但在我们的暂存环境中,我们遇到了常见的错误:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

根据我的理解,当您尝试连接到非https网址时会发生此错误。

  • 我们使用ngrok作为我们的本地隧道,其中有一个https网址并且工作正常。
  • 对于制作,我们也使用https://ourdomain.com,它可以正常工作。
  • 对于暂存,我们使用https://staging.ourdomain.com并发生错误。

我已经看到许多解决方案说明了这一点:

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

但我的雇主反对禁止ATS只是为了上班,他也反对为staging URL添加例外的想法。

为什么我们的暂存网址会引发此错误或如何修复它?

ATS诊断输出:

Starting ATS Diagnostics

Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https://staging.domain.co.
A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error.
================================================================================

Default ATS Secure Connection
---
ATS Default Connection
ATS Dictionary:
{
}
Result : PASS
---

================================================================================

Allowing Arbitrary Loads

---
Allow All Loads
ATS Dictionary:
{
    NSAllowsArbitraryLoads = true;
}
Result : PASS
---

================================================================================

Configuring TLS exceptions for staging.domain.co

---
TLSv1.2
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.2";
        };
    };
}
Result : PASS
---

---
TLSv1.1
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.1";
        };
    };
}
Result : PASS
---

---
TLSv1.0
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.0";
        };
    };
}
Result : PASS
---

================================================================================

Configuring PFS exceptions for staging.domain.co

---
Disabling Perfect Forward Secrecy
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring PFS exceptions and allowing insecure HTTP for staging.domain.co

---
Disabling Perfect Forward Secrecy and Allowing Insecure HTTP
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring TLS exceptions with PFS disabled for staging.domain.co

---
TLSv1.2 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.2";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.1 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.1";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.0 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.0";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for staging.domain.co

---
TLSv1.2 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.2";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.1 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.1";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.0 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "staging.domain.co" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.0";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

1 个答案:

答案 0 :(得分:8)

App Transport Security不仅仅是HTTP与HTTPS。您需要使用正确配置的服务器+证书以避免ATS问题。来自Apple docs [1]:

  

服务器必须至少支持传输层安全性(TLS)   协议版本1.2。连接密码仅限于那些   提供前瞻性保密。证书必须使用SHA256或   更大的签名哈希算法,具有2048位或更高位   RSA密钥或256位或更大的椭圆曲线(ECC)密钥。无效   证书导致硬故障并且没有连接。

如果您使用的是OS X 10.11(或更高版本),则可以使用nscurl进行故障排除。弹出一个终端然后运行:

/usr/bin/nscurl --ats-diagnostics https://staging.ourdomain.com

[1] https://developer.apple.com/library/ios/technotes/App-Transport-Security-Technote/index.html