Alamofire https 请求仅在 NSExceptionAllowsInsecureHTTPLoads 设置为 true 时有效

Alamofire https request only works if NSExceptionAllowsInsecureHTTPLoads is set to true

我在 Xcode10 中使用 Swift 开发了一个应用程序(应用程序名称:"TerminalsPOC")。我正在使用 Alamofire 向我组织的内部网站 api(我们将 url 称为“https://example.com:50001/RESTAdapter/toolbox/getMyData”)发出 https 请求。我有一个 class 和一个 class 级别的变量来引用会话管理器:

// Swift code
    let serverTrustPolicies: [String: ServerTrustPolicy] = [
        “example.com": .pinCertificates(
            certificates: ServerTrustPolicy.certificates(in: Bundle(for: type(of: self))),
            validateCertificateChain: false,
            validateHost: true
        )
    ]

     sessionManager = SessionManager(
        serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
    )

    sessionManager.request(url, method: .get) ... 

我已将必要的 .cer 证书导入到应用程序的捆绑包中。我保留了默认的 ATS 设置,但添加了一个 NSExceptionDomain。相关的 info.plist 部分看起来像

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <false/>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>example.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>

只要 NSExceptionAllowsInsecureHTTPLoads 设置为 true,此方法就有效。如果我将其设置为 false,请求将失败并显示消息:发生 SSL 错误并且无法建立与服务器的安全连接。 [-1200]

2018-12-07 11:55:42.122423-0700 TerminalsPOC[27191:371810] ATS failed system trust 2018-12-07 11:55:42.122530-0700 TerminalsPOC[27191:371810] System Trust failed for [2:0x600001fad740]

2018-12-07 11:55:42.122637-0700 TerminalsPOC[27191:371810] TIC SSL Trust Error [2:0x600001fad740]: 3:0

2018-12-07 11:55:42.125928-0700 TerminalsPOC[27191:371810] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

2018-12-07 11:55:42.126109-0700 TerminalsPOC[27191:371810] Task <54567E3C-2BBC-4227-9C0A-FC60370A10AA>.<1> HTTP load failed (error code: -1200 [3:-9802])

2018-12-07 11:55:42.126872-0700 TerminalsPOC[27191:371812] Task <54567E3C-2BBC-4227-9C0A-FC60370A10AA>.<1> finished with error - code: -1200

2018-12-07 11:55:42.140600-0700 TerminalsPOC[27191:371810] Task <54567E3C-2BBC-4227-9C0A-FC60370A10AA>.<1> load failed with error Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=( "", "" ), NSErrorClientCertificateStateKey=0, NSErrorFailingURLKey=https://example.com:50001/RESTAdapter/toolbox/getMyData, NSErrorFailingURLStringKey=https://example.com:50001/RESTAdapter/toolbox/getMyData, NSUnderlyingError=0x6000024e89f0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=( "", "" )}}, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <54567E3C-2BBC-4227-9C0A-FC60370A10AA>.<1>" ), _kCFStreamErrorCodeKey=-9802, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <54567E3C-2BBC-4227-9C0A-FC60370A10AA>.<1>, NSURLErrorFailingURLPeerTrustErrorKey=, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made.} [-1200]

我尝试了 运行 “nscurl --ats-diagnostics https://example.com:50001/RESTAdapter/toolbox/getMyData”,响应包括以下内容:

Default ATS Secure Connection

--- ATS Default Connection Result : PASS

========

Allowing Arbitrary Loads

--- Allow All Loads Result : PASS

========= Configuring TLS exceptions for example.com

--- TLSv1.3 2018-12-07 10:59:17.492 nscurl[24303:331847] NSURLSession/NSURLConnection HTTP load failed

(kCFStreamErrorDomainSSL, -9800) Result : FAIL

--- TLSv1.2 Result : PASS

--- TLSv1.1 Result : PASS

--- TLSv1.0 Result : PASS

============ Configuring PFS exceptions for example.com

--- Disabling Perfect Forward Secrecy Result : PASS

========== Configuring PFS exceptions and allowing insecure HTTP for example.com

--- Disabling Perfect Forward Secrecy and Allowing Insecure HTTP Result : PASS

我觉得这一切都还不错。我一定是遗漏了什么。

所以我的问题是:

1. 为什么将 NSExceptionAllowsInsecureHTTPLoads 设置为 true 会导致调用工作,因为它是一个 https 请求(没有重定向)?我以为这个设置只影响 http 调用,应该不会影响 https 调用。

2. 如何在不设置 NSExceptionAllowsInsecureHTTPLoads(这似乎是 hack/work-around,不是吗)的情况下让这个 Web 请求工作?

本例中的问题是该应用 运行 在尚未安装所需证书的模拟器上运行。

安装并信任正确的(根)证书后,固定证书检查通过,然后可以将 NSExceptionAllowsInsecureHTTPLoads info.plist 设置回 "NO" .

我希望错误消息更明确。 :-/