11

ユーザーが Mobile Safari で https Web ページをロードしようとして、サーバーの証明書の検証チェックが失敗した場合 (期限切れ、失効、自己署名など)、ユーザーに警告メッセージが表示され、続行するかどうか尋ねられます。か否か。

同様に NSURLConnection は、実装者が最初に証明書をチェックする方法を決定し、失敗した場合の続行方法を決定する機能を提供します。そのため、この状況でも、ユーザーに警告を表示し、読み込みを続行する機会を提供することができます。ページかどうか。

ただし、証明書チェックに失敗した UIWebView で https ページをロードすると、動作はページのロードに失敗するだけのようです - didFailLoadWithError: は kCFURLErrorServerCertificateUntrusted で呼び出されますが、ユーザーには何も表示されません。

これは一貫性がありません。UIWebView の動作は、iPhone 内で一貫性を保つために Safari と同じように動作する必要がありますか? NSURLConnection がこれで完全な柔軟性を可能にするのは、まだ NSURLRequest:set AllowAnyHTTPSCertificate が非公開であることも気の毒です。

Safari と一貫性のある動作を実装する方法はありますか?このデフォルトの動作は、NSURLConnection が許可するのと同様の方法でカスタマイズできますか?

乾杯

PS なぜ誰かがこれをやりたいのかについてひいきに議論することは控えてください。どうもありがとうございました。

4

2 に答える 2

15

私はこれを行う方法を見つけました:

1) ページが読み込まれると失敗するため、次のような内容を didFailLoadWithError に追加します。

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
    if ([error.domain isEqualToString: NSURLErrorDomain])
    {
        if (error.code == kCFURLErrorServerCertificateHasBadDate        ||
            error.code == kCFURLErrorServerCertificateUntrusted         ||
            error.code == kCFURLErrorServerCertificateHasUnknownRoot    ||
            error.code == kCFURLErrorServerCertificateNotYetValid)
        {
        display dialog to user telling them what happened and if they want to proceed

2) ユーザーがページをロードしたい場合は、NSURLConnection を使用して接続する必要があります。

NSURLRequest *requestObj = [NSURLRequest requestWithURL:self.currentURL     cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:10.0];
self.loadingUnvalidatedHTTPSPage = YES;
[self.webView loadRequest:requestObj];

3) 次に、この変更を shouldStartLoadWithRequest に加えます。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
{
    if (self.loadingUnvalidatedHTTPSPage)
    {
        self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
        [self.connection start];
        return NO;
    }

4) NSURLConnectionDelegate を次のように実装します。

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    SecTrustRef trust = challenge.protectionSpace.serverTrust;
    NSURLCredential *cred;
    cred = [NSURLCredential credentialForTrust:trust];
    [challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
}


- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
{
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:self.currentURL cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:10.0];
    self.loadingUnvalidatedHTTPSPage = NO;
    [self.webView loadRequest: requestObj];
    [self.connection cancel];
}

それはすべてうまくいくようです。

于 2013-01-11T21:18:04.540 に答える
1

馬の口 より:

「UIWebView は、アプリが HTTPS サーバーの信頼評価をカスタマイズする方法を提供しません。パブリック API を使用してこの制限を回避することは可能ですが、簡単ではありません。これを行う必要がある場合は、開発者テクニカル サポート (dts @apple.com)

ソース: http://developer.apple.com/library/ios/#technotes/tn2232/_index.html

于 2013-01-10T22:59:18.680 に答える