web-dev-qa-db-ja.com

UIWebViewで無効なサーバー証明書を無視する

UIWebViewを使用してコンテンツを表示するiOSアプリがあります。次のようなコードでデータをロードします。

NSURL *url = [NSURL URLWithString:myURLString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_webView setDelegate:self];
[_webView loadRequest:request];

これは以前はHTTPリクエストで正常に機能していましたが、現在は自己署名SSL証明書を持つサーバーに対してHTTPSを使用しています。上記を実行すると、webView:didFailLoadWithError:デリゲートメソッドが呼び出され、次のエラーが発生します。

このサーバーの証明書は無効です。機密情報を危険にさらす可能性のある「blah.blah.blah.com」になりすましたサーバーに接続している可能性があります。

Mobile Safariでできるように、無効な証明書を無視してリクエストを続行します。

私はNSURLConnectionを使用するときにこの問題を回避する方法を見てきました(たとえば 古いiphone 3gでのHTTPSリクエスト を参照してください)、UIWebViewで何ができるか?

NSURLConnectionを使用してリクエストを作成し、そのloadHTMLString:baseURL:メソッドを呼び出して結果をWebビューに入れるようにコードを作り直すことができると思いますが、ページが複雑になると、画像、CSS、JavaScriptなどがあります。もっと簡単な方法はありますか?

26

ご注意ください:このAPIは現在サポートされておらず、実際には安全なテスト環境でのみ使用する必要があります。詳細については、こちらをご覧ください CocoaNeticsの記事

[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url Host]];を使用すると、証明書エラーを無視できます。また、これらのプライベートAPIへのアクセスを許可するには、ファイルの先頭に以下を追加する必要があります。

@interface NSURLRequest (DummyInterface)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)Host;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)Host;
@end
22
Darc

誰もが知っているように...隠されたインターフェースの上記の使用はアップルに受け入れられません。彼らはプライベートAPIの使用を探しており、それは許容できるソリューションではありません。したがって、上記の解決策を修正する方法として投稿しないでください。これは機能しますが、AppStoreで拒否を購入します。それは役に立たない。

以下は、無効なサーバー証明書を無視するACCEPTABLEメソッドです。 NSURLConnectionを使用して、次のようにWebページのデータを手動でロードする必要があります。

.
.
.
    //Create a URL object.
    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];
}
@end

ここで、resultDataは前にインスタンス化したNSMutableDataであり、urlとurlAddressはどちらもインスタンス化して他の場所に入力したものです。

残念ながら、現在のところ、有効な証明書がなくても、実際のUIWebViewがページを直接ロードする方法がわかりません。

あなた、GC

16
greg.casamento

キャンセルされたNSURLConnectionによってサイトが認証されると、UIWebViewがサイトにリクエストを送信できることがわかります。 ここに完全な説明があります。

私の知る限り、UIWebViewだけではそれは不可能です。私が理解しているように、NSURLConnectionを使用してすべてのHTTP/HTTPSモジョを処理し、その結果をUIWebView-loadHtmlString:baseURL:または-loadData:MIMEType:textEncodingName:baseURL:を介してフィードする必要があります。

0
Greg