iPhone - NTLM, Basic and other authorizations using async NSURLConnection

社会主义新天地 提交于 2019-12-11 01:58:27

问题


Here's an issue: I need to implement both HTTP basic authorization and MS NTLM authorization. I use asynchronous NSURLConnection so I receive

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

callback. The full code of this method looks like that:

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

The two global issues I've met so far using this method:

1) As per Charles sniffer, all the requests to the server are doubled (as per Apple Docs, it's an expected behaviour). However, it leads to lack of performance (two requests instead of just one) comparing to setting header directly, using setValue:forHTTPHeader:.

2) It's being called not for every request. For example, when I'm trying to grab an image from server, it returns 302 (redirect to login web page) HTTP code instead of 401 HTTP code, so this does not work at all.

What I want to accomplish, is to grab the correct Authorization header once and then put it manually in every subsequent NSMutableURLRequest I make. I can compose HTTP Basic authorization manually, it's pretty simple, but I can't compose NTLM header in the same manner, that's why I was relying on didReceiveAuthenticationChallenge: method.

Could you please point me out, how can I receive the Authorization header, that is set automatically by NSURLProtectionSpace, so each request will INITIALLY go authorized?

P.S. I tried to receive it from

[connection.currentRequest allHTTPHeaderFields];

but it returns an empty array. I'm fighting with that for more than two days, any help will be kindly appreciated!

来源:https://stackoverflow.com/questions/18510027/iphone-ntlm-basic-and-other-authorizations-using-async-nsurlconnection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!