我正在尝试在 iOS 8 的 WKWebView 中加载带有自签名证书的 HTTPS url,但它一直失败。与 UIWebView 一起使用的解决方法(使用 NSUrlRequest 中的 setAllowsAnyHTTPSCertificate)似乎不起作用。有谁知道任何解决方法?
我不需要对 AppStore 有效的解决方案,因为我只需要在开发阶段访问自签名证书站点,而不是在生产阶段,但这对于开发和测试服务器实例来说确实是个问题。
先感谢您。
我正在尝试在 iOS 8 的 WKWebView 中加载带有自签名证书的 HTTPS url,但它一直失败。与 UIWebView 一起使用的解决方法(使用 NSUrlRequest 中的 setAllowsAnyHTTPSCertificate)似乎不起作用。有谁知道任何解决方法?
我不需要对 AppStore 有效的解决方案,因为我只需要在开发阶段访问自签名证书站点,而不是在生产阶段,但这对于开发和测试服务器实例来说确实是个问题。
先感谢您。
这在 iOS 9 中已修复!WKWebView
最后调用webView(_:didReceiveAuthenticationChallenge:completionHandler:)
on WKNavigationDelegate
。不幸的是,如果您在 iOS 8 设备上运行内置于 Xcode 7 的代码(至少在我的初始测试中不是),这将不起作用。
在下面的示例中,我实际上并没有对证书做任何事情,只是让它通过而不做任何进一步的验证(对于生产代码来说显然是一个糟糕的计划)。有关他们希望您在此处执行的操作的更多详细信息,请参阅Apple 的文档(清单 3)。
迅速:
func webView(webView: WKWebView, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge,
completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
let cred = NSURLCredential.init(forTrust: challenge.protectionSpace.serverTrust!)
completionHandler(.UseCredential, cred)
}
斯威夫特 3:
let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!)
completionHandler(.useCredential, cred)
斯威夫特 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);
我花了很多时间研究这个问题,作为一个 ios 新手,我认为所提出的解决方案都不完整。因此,这就是我为使 WKWebView 在我的情况下工作所做的工作(非常简单的 Web 视图,需要访问仅用于开发的自签名证书):
第一件事:在我的根 Info.plist 文件中,我添加了“App Transport Security Settings”作为字典,并添加了值为 YES 的“Allow Arbitrary Loads”项。
第二:我将此代码添加到我的 ViewController(继承 UIViewController 和 WKNavigationDelegate) - 这来自其他地方的几个答案
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
guard let serverTrust = challenge.protectionSpace.serverTrust else { return completionHandler(.useCredential, nil) }
let exceptions = SecTrustCopyExceptions(serverTrust)
SecTrustSetExceptions(serverTrust, exceptions)
completionHandler(.useCredential, URLCredential(trust: serverTrust))
}
请注意,此解决方案可能会被应用商店拒绝 - 我将使用值为 NO 的“允许任意负载”项目提交给应用商店。
我有同样的错误,并尝试使用上面最投票的答案来解决它,我使用以下代码创建了一个NSURLCredential
对象,但它失败了。
NSURLCredential * credential = [[NSURLCredential alloc] initWithTrust:[challenge protectionSpace].serverTrust];
然后我在Apple Developer Forums找到了解决方案。这帮助了我:
- (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]);
}
尝试这个:
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
if let serverTrust = challenge.protectionSpace.serverTrust {
let credential = URLCredential(trust: serverTrust)
completionHandler(.useCredential, credential)
}else{
completionHandler(.useCredential, nil)
}
}
看起来现阶段可能没有解决方案(iOS 8.1.1)。人们可能期望 WKNavigationDelegate 方法webView:didReceiveAuthenticationChallenge:completionHandler:
来处理这个问题,但是根据这个Apple 开发者论坛的讨论,一位 Apple 员工确认,当遇到自签名证书时,这个委托方法当前不会被调用。
在设备上的 Safari 中打开 URL 一次,系统将提示您选择接受证书。一旦被接受,它也应该在您的应用程序中工作,因为设备现在知道证书。这是针对每个设备的解决方法,它绝不会在发布时影响您的应用程序。
iOS 10+ 忽略 NSAllowsArbitraryLoads
:检查这里。并对其他标志保持谨慎,因为 Apple 将要求 AppStore 审查的理由。并忽略与 UIWebview 相关的解决方案,Apple 无论如何都会拒绝它。
这显然不适合大量目标受众。
webView(_:didReceive:completionHandler:)
websocket有一个未修复的 webkit 错误(自 2015 年以来!),它是不同的身份验证路由,因此目前无法覆盖系统默认行为。苹果论坛主题: