Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSURLConnectionDelegate willSendRequestForAuthenticationChallenge won't get called on iOS 8

My server provide several authentication methods: NTLM and digest.
My iOS client won't handle the NTLM authentication, so I implement the connection:willSendRequestForAuthenticationChallenge: delegate to reject the NTLM, then use correct credential only for the digest authentication challenge.
Everything works fine on iOS 7 so far.

But on iOS 8, I found a weird behavior:
the connection:willSendRequestForAuthenticationChallenge: delegate won't be called at most time (95%)!!

I got this error instead:

Error: Error Domain=NSPOSIXErrorDomain Code=54 "The operation couldn’t be completed. Connection reset by peer" 
UserInfo=0x16520fb0 {_kCFStreamErrorCodeKey=54, 
NSErrorPeerAddressKey=<CFData 0x16682e40 [0x2f752440]>{length = 16, capacity = 16, bytes = 0x10020d7eac12780b0000000000000000}, 
NSErrorFailingURLKey=http://SERVER_IP:SERVER_PORT/Tunnel/Message.aspx, 
NSErrorFailingURLStringKey=http://SERVER_IP:SERVER_PORT/Tunnel/Message.aspx, 
_kCFStreamErrorDomainKey=1}

Only 5% time the delegate is correctly called and work as usual.

Below shows how I send my request to server and handle the authentication challenge:

- (void)postRequest
{
    NSString *IP = SERVER_IP;
    int port = SERVER_PORT;

    NSString *url = [NSString stringWithFormat:@"http://%@:%d/Tunnel/Message.aspx", IP, port];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];

    NSString *xml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?><GetServerInfo></GetServerInfo>"];
    [request setHTTPBody: [xml dataUsingEncoding:NSUTF8StringEncoding]];

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    NSLog(@"%@", challenge.protectionSpace);

    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPDigest])
    {
        if ([challenge previousFailureCount] == 0)
        {
            [[challenge sender] useCredential:[NSURLCredential credentialWithUser:USERNAME
                                                                         password:PASSWORD
                                                                      persistence:NSURLCredentialPersistenceNone]
                   forAuthenticationChallenge:challenge];
        }
        else
        {
            [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
        }
    }
    else
    {
        [[challenge sender] rejectProtectionSpaceAndContinueWithChallenge:challenge];
    }
}

Those code work on iOS 7, willSendRequestForAuthenticationChallenge get called several times during the authentication challenge, but not even called any once on iOS 8!

Could this be a bug of iOS 8 or something changed since iOS 8?

like image 509
Davis Cho Avatar asked Aug 29 '14 10:08

Davis Cho


1 Answers

This happened to me when I was updating my iOS 7 app to iOS 8. We were using Oracle SOA as the middle ware and sunddenly it stopped calling the delegate methods. Below worked for me in both iOS8 and iOS7. (With Xcode 6.1)

  - (void) addBasicHTTPAuthenticationHeaders
    {
        NSString * wsUserName = @"userNameForWebService";
        NSString * wsPassword = @"passwordForWebService";

        NSString *authStr = [NSString stringWithFormat:@"%@:%@", wsUserName, wsPassword];
        NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
        NSString *authValue = [NSString stringWithFormat:@"Basic %@", [authData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]];
        [urlRequest setValue:authValue forHTTPHeaderField:@"Authorization"];
    }
like image 160
Charith Nidarsha Avatar answered Sep 28 '22 05:09

Charith Nidarsha