如何使用iOS 7的NSURLSession接受自签名的SSL证书

我有以下代码(快速实施):

func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace) -> Bool { return protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust } func connection(connection: NSURLConnection, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge) { if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { if challenge.protectionSpace.host == "myDomain" { let credentials = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust) challenge.sender.useCredential(credentials, forAuthenticationChallenge: challenge) } } challenge.sender.continueWithoutCredentialForAuthenticationChallenge(challenge) } 

它在iOS 8.x中完美工作但不起作用的iOS 7.x在iOS 7.x我有错误:

NSURLConnection / CFURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9813)

任何想法? 谢谢!!!

这两个connection:canAuthenticateAgainstProtectionSpace:connection:canAuthenticateAgainstProtectionSpace:反正在iOS 8中不推荐使用,所以你应该使用其他方法。

我在我的项目中使用的是NSURLSessionDelegate的委托方法。 坚持该协议,然后添加此方法:

 func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) { completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)) } 

然后,当您使用委托设置为自我初始化NSURLSession。 例如:

 var session = NSURLSession(configuration: configuration, delegate: self, delegateQueue:NSOperationQueue.mainQueue()) 

然后使用该会话实例在以下位置调用dataTaskWithRequest方法:

 var task = session.dataTaskWithRequest(request){ (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in if error != nil { callback("", error.localizedDescription) } else { var result = NSString(data: data, encoding: NSASCIIStringEncoding)! } } task.resume() 

完整的工作示例可以在这里find。

出于安全原因,如果您使用自签名证书,我build议还实施公钥固定( https://gist.github.com/edwardmp/df8517aa9f1752e73353

inheritanceURLSessionDelegate类

创build一个会话对象

 let config = URLSessionConfiguration.default let session = Foundation.URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main) let task = session.dataTask(with: httpRequest as URLRequest, completionHandler: {requestData, response, errorData -> Void in if errorData == nil { dataCallback(requestData! as NSData) } else { let error = NSError(domain: "Err-1001", code: 11, userInfo:nil) failureCallback(error) } }); task.resume() 

添加委托美沙德

 func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { completionHandler( .useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) } 

将其添加到您的info.plist文件中

 <key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>xyc.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSExceptionRequiresForwardSecrecy</key> <true/> <key>NSExceptionMinimumTLSVersion</key> <string>TLSv1.2</string> <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key> <false/> <key>NSThirdPartyExceptionRequiresForwardSecrecy</key> <true/> <key>NSThirdPartyExceptionMinimumTLSVersion</key> <string>TLSv1.2</string> <key>NSRequiresCertificateTransparency</key> <false/> </dict> </dict> </dict>