我正在尝试向我的应用中的安全服务器发出POST请求,但没有证书。当我提出请求时,我在控制台中收到这些错误:
2018-04-24 16:14:22.942030-0400 TIC TCP Conn Failed [8:0x60000017c440]: 1:54 Err(54)
2018-04-24 16:14:22.942779-0400 Task <1E09E1AE-CE51-48C4-9A56-F3738B8FD68F>.<1> HTTP load failed (error code: -1005 [1:54])
2018-04-24 16:14:22.943219-0400 [93037:8075678] Task <1E09E1AE-CE51-48C4-9A56-F3738B8FD68F>.<1> finished with error - code: -1005
在URLSession:didReceiveChallenge
我没有验证证书;我只是打电话给continueWithoutCredentialForAuthenticationChallenge
。
我将我的域名设置为Info.plist中的ATS例外:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>mydomain.net</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
我找不到有关Err(54)
和error code: -1005
含义的任何文档,因此我在排除故障时遇到了障碍。值得一提的是,我必须将我的Mac连接到我的VPN来ping这个服务器,并且我在我的模拟器中运行它。
我希望听到一些可能出错的建议以及如何解决。
答案 0 :(得分:1)
您需要了解允许您的应用执行的ATS设置。
NSAllowsArbitraryLoads
设置为true允许您通过HTTP连接到任何服务器。因此,您可以尝试使用http
方案从任何网址加载数据。
您的例外域设置(假设您的&#34; mydomain.net&#34;是实际值的占位符)将允许您连接到&#的任何子域(因为NSIncludesSubdomains
为真) 34; mydomain.net&#34;使用:
NSTemporaryExceptionAllowsInsecureHTTPLoads
设置为true)
NSThirdPartyExceptionRequiresForwardSecrecy
设置为true)首先,验证您是否可以连接到您尝试从相关设备上的Safari连接的URL(在本例中为模拟器)。 Safari不强制执行ATS要求,因此您可以查看它是否与ATS相关。如果您无法访问该URL,则它与该连接有关。这可能是服务器无法访问,或者可能是安全连接证书的问题。如果这是问题,您可以摆脱尝试解决问题时添加的任何ATS例外。
如果您可以连接到资源,请尝试验证未满足哪些ATS要求,以便添加适当的例外。在Mac上的终端中,运行以下命令以获取有关服务器是否符合ATS规则的报告:
nscurl --ats-diagnostics <url>
这将告诉您服务器是否不支持前向保密,或者TLS版本是否过低。然后,您可以为该域添加特定的ATS例外。
我仍然认为还有另一个问题,因为日志中的ATS错误通常非常清楚。您的错误似乎是一般连接问题。您提到将Mac连接到VPN。您的VPN是否要求您使用HTTP / HTTPS代理?如果是这样,当代理需要某些类型的身份验证时,我遇到了模拟器试图使用mac代理的问题。如果您的http代理需要身份验证,您可以尝试使用像Charles Proxy这样的中间人。即设置Charles Proxy以对您公司的代理进行身份验证,然后指向Mac /模拟器以使用应配置为不需要身份验证的本地Charles代理。
答案 1 :(得分:0)
我发现问题出在我处理URLSession:didReceiveChallenge
的方式上。我只是打电话给continueWithoutCredentialForAuthenticationChallenge
。我要做的就是用completionHandler
来获取凭证:
SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
ASSERT(nil != serverTrust);
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);