iPhone - 使用异步NSURLConnection的NTLM,Basic和其他授权

时间:2013-08-29 11:42:20

标签: ios authorization nsurlconnection ntlm

这是一个问题:我需要实现HTTP基本授权和MS NTLM授权。我使用异步NSURLConnection,所以我收到了

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

回调。这个方法的完整代码如下:

-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    NSString* authMethod = [[challenge protectionSpace] authenticationMethod];
    NSLog(@"Authentication method: %@", authMethod);

    NSString *userName = self.login;
    if ([authMethod isEqualToString:NSURLAuthenticationMethodNTLM]) {
        userName = [userName lastElementAfterSlash];
    }
    else if ([authMethod isEqualToString:NSURLAuthenticationMethodNegotiate]) {
        userName = [NSString stringWithFormat:@"%@@%@", userName, self.url.host];
    }

    if ([challenge previousFailureCount] <= 1) {
        NSURLCredential *credential = [NSURLCredential credentialWithUser:userName password:self.password persistence:NSURLCredentialPersistenceForSession];
        [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];

        NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
                                                  initWithHost:[self.url host]
                                                  port:0
                                                  protocol:self.url.scheme
                                                  realm:[self.url host]
                                                  authenticationMethod:authMethod];
        [[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential
                                                            forProtectionSpace:protectionSpace];
    }
    else {
        NSLog(@"Authentication error");
        NSLog(@"Failed login with status code: %d", [(NSHTTPURLResponse*)[challenge failureResponse]statusCode]);
        [[challenge sender] cancelAuthenticationChallenge:challenge];   
    }
}

到目前为止我使用这种方法遇到的两个全局问题:

1)根据Charles嗅探器,对服务器的所有请求都加倍(根据Apple Docs,这是预期的行为)。但是,与使用setValue:forHTTPHeader:。

直接设置标题相比,它会导致性能不足(两个请求而不是一个)

2)不是每个请求都被调用。例如,当我尝试从服务器获取图像时,它返回302(重定向到登录网页)HTTP代码而不是401 HTTP代码,因此这根本不起作用。

我想要完成的是获取正确的Authorization标头一次,然后将其手动放入我制作的每个后续NSMutableURLRequest中。我可以手动编写HTTP Basic授权,这很简单,但是我不能以相同的方式编写NTLM头,这就是我依赖didReceiveAuthenticationChallenge:方法的原因。

请您指出,我如何收到NSURLProtectionSpace自动设置的授权标题,以便每个请求都能获得授权?

P.S。我试图从

收到它
[connection.currentRequest allHTTPHeaderFields];

但它返回一个空数组。我正在与之抗争超过两天,任何帮助都将受到赞赏!

0 个答案:

没有答案