IOS 8用のWKWebViewで自己署名証明書を使用してHTTPS URLをロードしようとしていますが、失敗し続けます。 UIWebViewで使用されている回避策(NSUrlRequestのsetAllowsAnyHTTPSCertificateを使用)は機能していないようです。誰かが回避策を知っていますか?
本番環境ではなく、開発段階で自己署名証明書サイトにアクセスするだけでよいので、AppStoreに有効なソリューションは必要ありませんが、サーバーインスタンスの開発とテストには本当に問題があります。
前もって感謝します。
これはiOS 9で修正されました! WKWebView
は、最終的にWKNavigationDelegate
でwebView(_:didReceiveAuthenticationChallenge:completionHandler:)
を呼び出します。残念ながら、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);
これを試して:
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開発者フォーラムのディスカッション an Apple遭遇しました。
同じエラーがあり、上記の最多回答を使用して解決しようとしました。次のコードを使用して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]);
}
私の場合、HTTPまたはHTTPSのURLを読み込むために次のように動作します
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
return completionHandler(.useCredential, nil)
}
http://www.example.com
などの安全でないHTTP URLをロードする場合は、次のようにInfo.plist
を開いてNSExceptionAllowsInsecureHTTPLoads
をオンにする必要があります。
デバイスのSafariでURLを1回開くと、証明書を受け入れるオプションが表示されます。証明書がデバイスで認識されるようになったら、アプリでも機能するはずです。これはデバイスごとの回避策であり、リリース時にアプリに影響を与えることはありません。
私はこれを調べるのに多くの時間を費やしましたが、ios初心者として、提案された解決策はどれも私の意見では完全ではありませんでした。だから、私の場合にWKWebViewを動作させるために私がやったことです(dev onlyの自己署名証明書にアクセスする必要がある非常に簡単なWebビュー):
まず、ルートのInfo.plistファイルに、「App Transport Security Settings」を辞書として追加し、「Allow Arbitrary Loads」アイテムを値YESで追加しました。
2番目:このコードを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の値でアプリストアに送信します