我有以下代码(
swift实现):
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)
任何想法?
谢谢!!!
解决方法
两个连接:canAuthenticateAgainstProtectionSpace:和连接:didReceiveAuthenticationChallenge:在iOS 8中已被弃用,所以你应该使用其他方法.
我在项目中使用的是NSURLSessionDelegate的委托方法.坚持那个协议,然后添加这个方法:
func URLSession(session: NSURLSession,didReceiveChallenge challenge: NSURLAuthenticationChallenge,completionHandler: (NSURLSessionAuthChallengeDisposition,NSURLCredential!) -> Void) { completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential,NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)) }
然后,当您使用委派设置为self时,初始化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()
完整的工作实例可以找到here.
出于安全考虑,如果您使用自签名证书,我建议同时执行公钥固定(https://gist.github.com/edwardmp/df8517aa9f1752e73353)