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

Posted

技术标签:

【中文标题】如何在 UIWebView 中显示身份验证质询?【英文标题】:How to display the Authentication Challenge in UIWebView? 【发布时间】:2010-12-18 16:47:17 【问题描述】:

我正在尝试通过 UIWebView 访问安全网站。当我通过 safari 访问它时,我收到了身份验证挑战,但同样的问题没有出现在应用程序的 UIWebView 中。我怎样才能让它出现?

任何指针、示例代码或链接都会非常有帮助。非常感谢。

【问题讨论】:

【参考方案1】:

这实际上非常简单...我相信您可以在显示身份验证挑战委托时显示 UIAlertView(或在加载 URL 之前,如果您确定您正在点击的 URL 会提示验证登录信息)。无论如何,诀窍是创建自己的NSURLConnection,然后我会做一些逻辑来保存是否使用了授权委托。

- (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;

【讨论】:

不适用于 POST。即使对此进行简单的修改仍然不适用于 POST。 这不适用于任何未经身份验证的请求(_authed 始终 == NO 并触发无限循环)。即使你解决了这个问题,这仍然不起作用,因为 shouldStartLoadWithRequest 会在每个网页上多次触发,最终导致网页视图加载的最后一个 url 请求是网页视图中显示的唯一内容。 将“_authed = YES”添加到 didReceiveResponse。当服务器由于某种原因没有发送质询请求时,这可以防止无限循环。 答案有几个问题,但它给出了解决已验证请求问题的基本概念。 好像在连接中断的时候,auth数据丢失了,而_authed还是YES,再也没有机会进行auth了。【参考方案2】:

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

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

【讨论】:

同一网络上的某人可以清楚地看到请求。 => 使用带有 SSL 证书的 https 可以解决这个问题。您可以使用 Wireshark 等嗅探器进行检查。【参考方案3】:

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

【讨论】:

如果已经收到响应,取消连接如何防止流量翻倍?【参考方案4】:

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

正如 y5h 所说,将 `_authed = YES' 添加到 didReceiveResponse 方法中,这将停止无限循环。即使身份验证不成功,您也需要将其视为已通过身份验证,因此如果不需要身份验证,它将尝试继续加载页面,如果确实需要身份验证,那么它将像往常一样失败。

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

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

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

编辑:如果页面完全加载,则上述方法会出现问题,然后加载更多嵌入内容,与 facebook 中断,这是迄今为止我看到的唯一情况

这将使网址在网站尝试加载时通过。我不确定是否可以安全地假设初始请求之后的每个 url 都是嵌入内容,但就我的目的而言,它似乎有效,所以也许它也适合你。

另外,使用

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

因为

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

已被贬低,对我来说,您无法使用它们对 https 网站进行身份验证

【讨论】:

【参考方案5】:

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

它包含一个示例,展示了如何使用UIAlertView 向用户询问密码,并且可以很容易地适应例如从本地数据库返回已保存的密码。

免责声明:我与 Jive 没有任何关系,我也从未加入过,这只是一个工具的建议,它在为此苦苦挣扎了几天后帮助了我。

【讨论】:

以上是关于如何在 UIWebView 中显示身份验证质询?的主要内容,如果未能解决你的问题,请参考以下文章

如何将基本身份验证质询转发到报告管理器 url

身份验证质询后未调用 URLSession 委托

在 ReactJS 中的 Spotify API 上为 PKCE 身份验证创建代码验证器和质询

在 AWS Cognito 中回答 NEW_PASSWORD_REQUIRED 质询后继续使用自定义身份验证流程

Python Cassandra:未发送身份验证质询,这是可疑的,因为驱动程序需要身份验证

反向代理后面的 .NET 6 OAuth 身份验证:质询时重定向 url 错误