ios 在 WKWebView 中允许未经验证的 ssl 证书
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27100540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Allow unverified ssl certificates in WKWebView
提问by Roi
I'm trying to load a HTTPS url with an self-signed certificate in a WKWebView for iOS 8 and it keeps failing. The workaround used with UIWebView (using setAllowsAnyHTTPSCertificate from NSUrlRequest) doesn't seem to work. Does anyone know of any workaround?
我正在尝试在 iOS 8 的 WKWebView 中加载带有自签名证书的 HTTPS url,但它一直失败。与 UIWebView 一起使用的解决方法(使用来自 NSUrlRequest 的 setAllowsAnyHTTPSCertificate)似乎不起作用。有谁知道任何解决方法?
I do not need a solution that is valid for AppStore, as I only need to access self-signed certificate sites on development phases, not on production, but it's really a problem for development and testing server instances.
我不需要对 AppStore 有效的解决方案,因为我只需要在开发阶段访问自签名证书站点,而不是在生产阶段,但这对于开发和测试服务器实例来说确实是一个问题。
Thank you in advance.
先感谢您。
回答by jvoll
This is fixed in iOS 9! WKWebView
finally makes calls to webView(_:didReceiveAuthenticationChallenge:completionHandler:)
on WKNavigationDelegate
. Unfortunately this does not work if you run code built in Xcode 7 on iOS 8 devices (at least not in my initial testing).
这已在 iOS 9 中修复!WKWebView
最后调用webView(_:didReceiveAuthenticationChallenge:completionHandler:)
on WKNavigationDelegate
。不幸的是,如果您在 iOS 8 设备上运行在 Xcode 7 中构建的代码(至少在我的初始测试中不是),这将不起作用。
In my example below, I'm not actually doing anything with the cert and just letting it pass through without doing any further validation (obviously a bad plan for production code). See Apple's docs(Listing 3) for more details of what they want you to do here.
在我下面的示例中,我实际上并没有对证书做任何事情,只是让它通过而不做任何进一步的验证(对于生产代码来说显然是一个糟糕的计划)。有关他们希望您在此处执行的操作的更多详细信息,请参阅Apple 的文档(清单 3)。
Swift:
迅速:
func webView(webView: WKWebView, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge,
completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
let cred = NSURLCredential.init(forTrust: challenge.protectionSpace.serverTrust!)
completionHandler(.UseCredential, cred)
}
Swift 3:
斯威夫特 3:
let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!)
completionHandler(.useCredential, cred)
Swift 4:
斯威夫特 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
目标-C
NSURLCredential * credential = [[NSURLCredential alloc] initWithTrust:[challenge protectionSpace].serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
回答by guozqzzu
I have the same error, and try to solve it using the Most Voted answer above, I used the following code to create a NSURLCredential
object, but it failed.
我有同样的错误,并尝试使用上面投票最多的答案来解决它,我使用以下代码创建了一个NSURLCredential
对象,但它失败了。
NSURLCredential * credential = [[NSURLCredential alloc] initWithTrust:[challenge protectionSpace].serverTrust];
Then I found a solution in Apple Developer Forums. This helped me :
然后我在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]);
}
回答by Faipdeoiad
Try this:
尝试这个:
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)
}
}
回答by user2067021
Looks like there may not be a solution at this stage (iOS 8.1.1). One might have expected the WKNavigationDelegate method webView:didReceiveAuthenticationChallenge:completionHandler:
to handle this, but based on this Apple developer forum discussionan Apple employee confirms that this delegate method currently doesn't get called when self-signed certificates are encountered.
看起来现阶段可能没有解决方案(iOS 8.1.1)。人们可能期望 WKNavigationDelegate 方法webView:didReceiveAuthenticationChallenge:completionHandler:
来处理这个问题,但根据这个Apple 开发者论坛讨论,一位 Apple 员工确认当遇到自签名证书时,当前不会调用此委托方法。
回答by simong5443
I spent a lot of time looking into this, as an ios newbie, none of the solutions proposed were complete in my opinion. So here is what I did to get WKWebView to work in my case (very simple web view that needs access to self signed cert for dev only):
我花了很多时间研究这个,作为一个 ios 新手,在我看来,提出的解决方案都不是完整的。因此,这里是我做过什么让WKWebView工作在我的情况(需要自签名的证书的访问非常简单的Web视图仅开发):
First thing: in my root Info.plist file, I added "App Transport Security Settings" as a dictionary, and add "Allow Arbitrary Loads" item with a value of YES.
第一件事:在我的根 Info.plist 文件中,我添加了“App Transport Security Settings”作为字典,并添加了值为 YES 的“Allow Arbitrary Loads”项。
Second: I added this code to my ViewController (inherits UIViewController and WKNavigationDelegate) - this was sourced from several answers elsewhere
第二:我将此代码添加到我的 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))
}
NOTE THAT THIS SOLUTION WILL LIKELY BE REJECTED BY THE APP STORE - I WILL SUBMIT TO THE APP STORE WITH "Allow Arbitrary Loads" ITEM WITH A VALUE OF NO.
请注意,此解决方案可能会被应用程序商店拒绝 - 我将向应用程序商店提交值为“否”的“允许任意加载”项目。
回答by dogsgod
Open the URL in Safari on the device once, there you will be prompted with the option to accept the certificate. Once accepted it should work in your app as well, as the certificate is now known to the device. This is a per device workaround, it will in no way affect your app at release time.
在设备上的 Safari 中打开 URL 一次,系统会提示您选择接受证书。一旦被接受,它也应该在您的应用程序中工作,因为设备现在知道该证书。这是每个设备的解决方法,它不会在发布时影响您的应用程序。