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" .
我希望错误消息更明确。 :-/
我在 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" .
我希望错误消息更明确。 :-/