在WKWebView中允许未经validation的SSL证书

我试图在WKWebView for iOS 8中加载带有自签名证书的HTTPS URL,并且一直保持失败状态。 用于UIWebView的解决方法(使用NSUrlRequest的setAllowsAnyHTTPSCertificate)似乎不起作用。 有谁知道任何解决方法?

我不需要一个适用于AppStore的解决scheme,因为我只需要在开发阶段而不是在生产阶段访问自签名证书站点,但这对于开发和testing服务器实例来说确实是一个问题。

先谢谢你。

这是固定在iOS 9! WKWebView最终在WKNavigationDelegate上调用webView(_:didReceiveAuthenticationChallenge:completionHandler :)。 不幸的是,如果你在iOS 8设备上运行Xcode 7中构build的代码(至less不是在我的初始testing中),这是行不通的。

在我的下面的例子中,我并没有对cert做任何事情,只是让它通过而不做任何进一步的validation(显然是生产代码的糟糕计划)。 查看苹果的文档 (清单3),了解他们希望在这里做什么的更多细节。

迅速:

func webView(webView: WKWebView, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) { let cred = NSURLCredential.init(forTrust: challenge.protectionSpace.serverTrust!) completionHandler(.UseCredential, cred) } 

Swift 3:

 let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!) completionHandler(.useCredential, cred) 

Swift 4:

 func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!) completionHandler(.useCredential, cred) } 

Objective-C的

 NSURLCredential * credential = [[NSURLCredential alloc] initWithTrust:[challenge protectionSpace].serverTrust]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential); 

看起来在这个阶段可能没有解决scheme(iOS 8.1.1)。 有人可能会期望WKNavigationDelegate方法webView:didReceiveAuthenticationChallenge:completionHandler: didReceiveAuthenticationChallenge webView:didReceiveAuthenticationChallenge:completionHandler:来处理这个问题,但是基于这个苹果开发者论坛的讨论 ,苹果员工确认这个委托方法当前遇到自签名证书时不会被调用。

我有同样的错误,并尝试使用上面的最投票答案解决它,我用下面的代码来创build一个NSURLCredential对象,但它失败了。

 NSURLCredential * credential = [[NSURLCredential alloc] initWithTrust:[challenge protectionSpace].serverTrust]; 

然后我在苹果开发者论坛find了一个解决scheme 这帮助了我:

 - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { NSLog(@"Allow all"); SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; CFDataRef exceptions = SecTrustCopyExceptions (serverTrust); SecTrustSetExceptions (serverTrust, exceptions); CFRelease (exceptions); completionHandler (NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:serverTrust]); } 

在设备上的Safari中打开URL一次,在那里你将被提示select接受证书。 一旦被接受,它也应该在你的应用中工作,因为证书现在已经被设备所知晓。 这是每个设备的解决方法,它不会在发布时间影响您的应用程序。

url对象:

 NSURL *url = [NSURL URLWithString:urlAddress]; NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:requestObj delegate:self]; [connection start]; 

然后,将其添加到您的代表:

 - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]; } - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; } else { [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; } } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [resultData appendData:data]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSString *htmlString = [[NSString alloc] initWithBytes:[resultData bytes] length:[resultData length] encoding:NSUTF8StringEncoding]; [webView loadHTMLString:htmlString baseURL:url]; }