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?
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"];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With