如何在UIWebView中显示身份验证质询?

时间:2009-11-20 11:28:33

标签: http uiwebview basic-authentication

我正试图通过UIWebView访问一个安全的网站。当我通过safari访问它时,我得到了一个身份验证挑战,但同样的情况并没有出现在应用程序的UIWebView中。如何让它出现?

任何指针,示例代码或链接都将非常有用。非常感谢。

5 个答案:

答案 0 :(得分:36)

实际上非常简单......我确信你可以在显示auth挑战代表时显示UIAlertView(或者在加载URL之前,如果你确定你要点击的URL会提示auth登录信息)。无论如何,诀窍是创建自己的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;
}

答案 1 :(得分:5)

您还可以在网址中提供您的凭据。 只需在“http://”和“page url”之间添加用户名和密码即可。

NSString *urlString = @"http://username:password@domain.com/home";
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]];

答案 2 :(得分:4)

如您所知,UIWebView不提供与服务器通信的机会。 我用这种方式解决了这个问题:在UIWebView的委托方法shouldStartLoadWithRequest中我启动了另一个与NSURLConnection的连接,并且已经在委托NSURLConnection的方法中,didReceiveAuthenticationChallenge处理了来自服务器的сhallenge。 Аnd在方法didReceiveResponse(如果挑战来了)然后再次在同一个UIWebView加载相同的URL(挑战已经处理:)。不要忘记在didReceiveResponse中取消连接,否则会使流量加倍。

答案 3 :(得分:1)

如果您遇到Zach在Sahil的回答中所描述的症状:

如同y5h所说,将“_authed = YES”添加到didReceiveResponse方法,这将停止无限循环。即使auth不成功,你也需要把它当作authed处理,所以如果不需要身份验证,它会尝试继续加载页面,如果确实需要身份验证,那么它就会像正常一样失败。

对于第二个症状,其中shouldStartLoadWithRequest:多次触发(由于网页上的嵌入内容)并且它只显示最后加载的内容而不是整个网页,请执行以下操作:

在shouldStartLoadWithRequest:方法中,将其添加到顶部

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

编辑:如果页面完全加载,上面的方法有问题,然后加载更多的嵌入内容,打破facebook,这是迄今为止唯一的案例

当网站尝试加载时,这会让网址通过。我不确定是否可以安全地假设初始请求后的每个网址都是嵌入式内容,但为了我的目的它似乎有效,所以也许它也适合你。

另外,使用

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

,因为

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

已被删除,对我来说,您无法使用https网站进行身份验证

答案 4 :(得分:0)

我想使用以下pod建议另一个答案: https://github.com/jivesoftware/JiveAuthenticatingHTTPProtocol

它包含一个示例,说明如何使用UIAlertView向用户询问密码,并且可以轻松调整以从本地数据库返回保存的密码。

免责声明:我与Jive没有任何关系,我也没有,这只是一个工具的建议,帮助我在这方面挣扎了好几天。