允许WKWebView中未经验证的ssl证书

Roi*_*Roi 28 ssl self-signed uiwebview ios wkwebview

我正在尝试在WKWebView for iOS 8中加载带有自签名证书的HTTPS URL并且它一直在失败.与UIWebView一起使用的解决方法(使用来自NSUrlRequest的setAllowsAnyHTTPSCertificate)似乎不起作用.有谁知道任何解决方法?

我不需要对AppStore有效的解决方案,因为我只需要在开发阶段访问自签名证书站点,而不是生产,但这对于开发和测试服务器实例来说确实是一个问题.

先感谢您.

jvo*_*oll 45

这已在iOS 9中修复!WKWebView最后将调用webView(_:didReceiveAuthenticationChallenge:completionHandler:)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)
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特3:

let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!)
completionHandler(.useCredential, cred)
Run Code Online (Sandbox Code Playgroud)

斯威夫特4:

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

Objective-C的

NSURLCredential * credential = [[NSURLCredential alloc] initWithTrust:[challenge protectionSpace].serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
Run Code Online (Sandbox Code Playgroud)


小智 9

我花了很多时间研究这个,作为一个 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))
}
Run Code Online (Sandbox Code Playgroud)

请注意,此解决方案可能会被应用程序商店拒绝 - 我将向应用程序商店提交值为“否”的“允许任意加载”项目。


guo*_*zzu 6

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

NSURLCredential * credential = [[NSURLCredential alloc] initWithTrust:[challenge protectionSpace].serverTrust];
Run Code Online (Sandbox Code Playgroud)

然后我在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]);
  }
Run Code Online (Sandbox Code Playgroud)


Fai*_*iad 5

尝试这个:

 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)
    }

}
Run Code Online (Sandbox Code Playgroud)


dog*_*god 1

在设备上的 Safari 中打开 URL 一次,系统将提示您接受证书的选项。一旦接受,它也应该在您的应用程序中工作,因为设备现在知道该证书。这是针对每个设备的解决方法,它绝不会影响您的应用程序在发布时。