NSURLSession与自定义身份验证挑战?

时间:2014-08-06 17:39:01

标签: ios authentication restful-authentication nsurlsession

我们的应用程序使用NSURLSession来使用RESTful服务调用。呼叫本身通过反向代理进行路由,以辅助后端的会话管理,安全性等。我们遇到的唯一问题与身份验证有关。当用户尝试通过浏览器或REST调用访问受保护资源并且未经过身份验证时,反向代理会显示HTML登录页面。

问题是,我们希望利用NSURLSession自动处理身份验证质询的能力。但是,NSURLSession无法识别我们正在返回身份验证质询,因为没有HTTP 401或其他错误代码返回给客户端。反向代理发回200,因为HTML已成功传递。我们能够通过检查客户端中的HTML来识别它是登录页面,但我们希望能够使用自定义NSURLAuthenticationChallenge来处理身份验证(如果可能的话),以便{{验证成功后,可以重试请求。

我们是否有办法认识到我们正在NSURLSession内找回登录页面并告诉completionHandler我们是否真的回到了身份验证挑战中?或者NSURLSession要求我们收到HTTP错误代码(401等)

4 个答案:

答案 0 :(得分:4)

有几种可能性浮现在脑海中。

  1. 如果您正在使用NSURLSession的委托再现,则可以通过NSURLSessionTaskDelegate方法willPerformHTTPRedirection检测重定向到身份验证失败页面。< / p>

    您也可以通过检查任务currentRequest.URL来检测重定向,并查看是否还发生了重定向。正如文档所说,currentRequest&#34;通常与初始请求(originalRequest)相同,除非服务器通过重定向到不同的URL来响应初始请求。&#34

  2. 假设RESTful服务通常不会返回HTML,您可以查看NSURLResponse,确认它确实是NSHTTPURLResponse子类,然后查看{ {1}}确认allHeaderFields是否出现在回复的text/html中。这显然只有在身份验证页面返回包含Content-Type的{​​{1}}并且其他回复不包含的情况下才会有效(例如他们会Content-Type或类似的事情)

    无论如何,这可能看起来像:

    text/html

    其中,application/json可能定义如下:

    NSString *contentType = [self headerValueForKey:@"Content-Type" response:response];
    
    if ([contentType rangeOfString:@"text/html"].location != NSNotFound) {
        // handle it here
    }
    
  3. 在最坏的情况下,您可以检测HTML响应并使用类似HPPLE的内容进行解析,并以编程方式检测身份验证HTML响应。

    见Wenderlich的文章How to Parse HTML on iOS

  4. 但是坦率地说,我更愿意看到一个REST响应,用REST响应(或正确的身份验证失败挑战或非200响应)报告身份验证错误,而不是重定向到HTML页面。如果您有机会更改服务器响应,那将是我个人的偏好。

答案 1 :(得分:1)

您是否曾尝试将用户名和密码设置为NSMutableURLRequest的授权标头。

NSString *authorizationString = [[[NSString stringWithFormat:@"%@:%@",user, password] dataUsingEncoding:NSUTF8StringEncoding] base64Encoding]; 

[yourRequest setValue:[NSString stringWithFormat:@"Basic %@", authorizationString] forHTTPHeaderField:@"Authorization"];

这应该有效。

答案 2 :(得分:1)

身份验证挑战由40x响应中的WWW-Authenticate标头触发。

来自the documentation

  

除非服务器响应包含WWW-Authenticate标头,否则URL加载系统类不会调用其委托来处理请求质询。其他身份验证类型(例如代理身份验证和TLS信任验证)不需要此标头。

不幸的是,上面提到的代理身份验证不适用于您的反向代理/加速器方案。

答案 3 :(得分:0)

您可以尝试使用HTML Parser库(例如https://github.com/nolanw/HTMLReader)。

然后在完成处理程序块中,您可以评估响应以检查它是否是HTML页面,以及它是否包含登录表单。

我不知道这个库,但我想你可以像这样使用它:

HTMLDocument *document = [HTMLDocument documentWithString:responseObjectFromServer];
HTMLNode *node = [document firstNodeMatchingSelector:@"form.login"];
if(node) {
    // Perform second NSURLSession call with login data
}