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

Dee*_*kor 3 ios swift ios9

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

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
Run Code Online (Sandbox Code Playgroud)

根据我的理解,当您尝试连接到非httpsURL 时会发生此错误.

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

我已经看到许多解决方案说明这样做:

<key>NSAppTransportSecurity</key>
 <dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>
Run Code Online (Sandbox Code Playgroud)

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

任何想法为什么我们的暂存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
---

================================================================================
Run Code Online (Sandbox Code Playgroud)

Rya*_*eve 8

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

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

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

/usr/bin/nscurl --ats-diagnostics https://staging.ourdomain.com
Run Code Online (Sandbox Code Playgroud)

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