I have to do repeated asynchronous NSURLConnection requests to HTTPS server with SSL client certificate authentication.
The first NSURLConnection is send to check whether the server is valid and it correctly calls the delegate method didReceiveAuthenticationChallenge. I want to ignore the authenticte challenge for the first time, so i send continueWithoutCredentialForAuthenticationChallenge.
In connectionDidFinishLoading: delegate method, i call the sendHTTPREquest method again which creates another NSURLConnection to the same server, but this time with the computer name appended to the URL.
The problem is, the method didReceiveAuthenticationChallenge: is not being called for the next time when i create a new URL connection to the same server. Is it because that once we send continueWithoutCredentialForAuthenticationChallenge, it applies to all subsequent URLConnections.
I have tried erasing URL Cache, clearing the CookieStorage and resetting NSURLCredentialStorage, but the delegate method didReceiveAuthenticationChallenge: is never called
I also tried appending a random number to the end of the URL string, when creating the NSURLconnection for the next time, but the problem still exists.
How do i cancel the continueWithoutCredentialForAuthenticationChallenge for the next NSURLConnection.
The first NSURLConnection is send to check whether the server is valid and it correctly calls the delegate method didReceiveAuthenticationChallenge. I want to ignore the authenticte challenge for the first time, so i send continueWithoutCredentialForAuthenticationChallenge.
Code:
-(void) send HTTPRequest {
if (connectionForServerValidation)
url = @"https://test.mobile.com";
else
url = @"https://test.mobile.com?testPC";
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setCachePolicy: NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:3*60.];
[request setHTTPMethod:@"GET"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
serverConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:true];
}
- (void)connection:(NSURLConnection*)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge
{
NSLog(@"didReceiveAuthenticationChallenge");
if (connectionForServerValidation)
[[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
else {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate])
{
if (credentialExists)
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
else
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}
}
}
In connectionDidFinishLoading: delegate method, i call the sendHTTPREquest method again which creates another NSURLConnection to the same server, but this time with the computer name appended to the URL.
The problem is, the method didReceiveAuthenticationChallenge: is not being called for the next time when i create a new URL connection to the same server. Is it because that once we send continueWithoutCredentialForAuthenticationChallenge, it applies to all subsequent URLConnections.
Code:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if (connectionForServerValidation) {
[serverConnection cancel];
[serverConnection release];
serverConnection=nil;
connectionForServerValidation=false;
[self sendHTTPRequest];
}
else {
....
....
}
}
Code:
-(void) eraseURLCache {
[[NSURLCache sharedURLCache] removeCachedResponseForRequest :(NSURLRequest*) request];
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
}
-(void) eraseCookies{
NSURL *myURL = [[NSURL alloc] initWithString:url];
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookies = [cookieStorage cookiesForURL:myURL];
for (NSHTTPCookie *cookie in cookies)
{
NSLog(@"Deleting cookie for domain: %@", [cookie domain]);
[cookieStorage deleteCookie:cookie];
}
[myURL release];
}
- (void) eraseCredentials {
NSURLCredentialStorage *credentialsStorage = [NSURLCredentialStorage sharedCredentialStorage];
NSDictionary *allCredentials = [credentialsStorage allCredentials];
if ([credentialsStorage count] > 0) {
for (NSURLProtectionSpace *protectionSpace in allCredentials) {
if ([[protectionSpace host] isEqualToString:url){
NSDictionary *credentials = [credentialsStorage credentialsForProtectionSpace:protectionSpace];
for (NSString *credentialKey in credentials)
[credentialsStorage removeCredential:[credentials objectForKey:credentialKey] forProtectionSpace:protectionSpace];
}
}
}
}
How do i cancel the continueWithoutCredentialForAuthenticationChallenge for the next NSURLConnection.
Last edited: