在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]; }