web-dev-qa-db-ja.com

UIWebViewで認証チャレンジを表示する方法

UIWebViewを介して安全なWebサイトにアクセスしようとしています。 Safariからアクセスすると、認証のチャレンジが表示されますが、アプリケーションのUIWebViewに同じものが表示されません。どうすれば表示できますか?

ポインタ、サンプルコード、またはリンクは非常に役立ちます。どうもありがとう。

37
UVT

それは実際には非常に簡単です...認証チャレンジデリゲートが表示されているとき(またはURLをロードする前に、ヒットしているURLが認証ログイン情報を要求することが確実であることがわかっている場合)に、UIAlertViewを表示できると確信しています)。とにかく、トリックはあなた自身のNSURLConnectionを作成することです、そして私はauthデリゲートが使用されたかどうかを保存するためにいくつかのロジックを行います。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
{
    NSLog(@"Did start loading: %@ auth:%d", [[request URL] absoluteString], _authed);

    if (!_authed) {
        _authed = NO;
        /* pretty sure i'm leaking here, leave me alone... i just happen to leak sometimes */
        [[NSURLConnection alloc] initWithRequest:request delegate:self];
        return NO;
    }

    return YES;
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
{
    NSLog(@"got auth challange");

    if ([challenge previousFailureCount] == 0) {
        _authed = YES;
        /* SET YOUR credentials, i'm just hard coding them in, Tweak as necessary */
        [[challenge sender] useCredential:[NSURLCredential credentialWithUser:@"username" password:@"password" persistence:NSURLCredentialPersistencePermanent] forAuthenticationChallenge:challenge];
    } else {
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
{
    NSLog(@"received response via nsurlconnection");

    /** THIS IS WHERE YOU SET MAKE THE NEW REQUEST TO UIWebView, which will use the new saved auth info **/

    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:]];

    [_webView loadRequest:urlRequest];
}

- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection;
{
    return NO;
}
36
Sahil

資格情報をURLで提供することもできます。 「http://」と「ページURL」の間にユーザー名とパスワードを追加するだけです。

NSString *urlString = @"http://username:[email protected]/home";
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]];
6
Mickael West

ご存知のように、UIWebViewはサーバーと通信する機会を提供しません。この問題をこの方法で解決しました。UIWebViewのデリゲートメソッドshouldStartLoadWithRequestでNSURLConnectionを使用して別の接続を開始し、すでにデリゲートNSURLConnectionのメソッドでdidReceiveAuthenticationChallengeがサーバーからのチャレンジを処理しました。メソッドdidReceiveResponse(チャレンジが発生した場合)の次に、同じUIWebViewで同じURLをロードします(チャレンジはすでに処理されています:)。 didReceiveResponseで接続をキャンセルすることを忘れないでください。そうしないと、トラフィックが2倍になります。

4
alexandrmoroz

サヒルの回答のコメントでザックが説明した症状を経験している場合:

y5hも言ったように、didReceiveResponseメソッドに「_authed = YES」を追加すると、無限ループが停止します。認証が成功しなかった場合でも、認証されたかのように処理する必要があるため、認証が不要な場合はページの読み込みを続行し、認証が本当に必要な場合は、通常のように失敗します。

(Webページに埋め込まれたコンテンツが原因で)shouldStartLoadWithRequest:が複数回発生し、Webページ全体ではなく最後にロードされたものだけを表示する2番目の症状の場合、次のようにします。

shouldStartLoadWithRequest:メソッドで、これを先頭に追加します

if(webview.loading){ //if url requests come through while its loading, its probably embedded content
    return YES;
}

編集:ページが完全に読み込まれ、その後により多くの埋め込みコンテンツが読み込まれると、これまでに見られた唯一のケースであるfacebookで壊れてしまう上記の方法には問題があります

これにより、ウェブサイトの読み込み中にURLが通過します。最初のリクエスト後のすべてのURLが埋め込みコンテンツであると想定しても安全かどうかはわかりませんが、私の目的ではそれは機能しているように見えたので、おそらくあなたにも役立つでしょう。

また、使用

- (void) connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

なぜなら

connection:canAuthenticateAgainstProtectionSpace:
connection:didReciveAuthenticationChallenge:
connection:didCancelAuthenticationChallenge:

私は、それらが使用されているhttps Webサイトで認証できませんでした

1
Fonix

次のポッドを使用して別の回答を提案したいと思います: https://github.com/jivesoftware/JiveAuthenticatingHTTPProtocol

UIAlertViewを使用してユーザーにパスワードを要求する方法を示す例が含まれており、たとえばローカルDBから保存されたパスワードを返すように簡単に調整できます。

免責事項:私は決してJiveと提携していませんし、これまでに行ったこともありません。これは、これに何日も苦労した後に私を助けてくれたツールの提案にすぎません。

0
dvkch