Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

rinkedev

macrumors newbie
Original poster
Oct 28, 2011
1
0
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.
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 {
		....
		....
	}

}
I have tried erasing URL Cache, clearing the CookieStorage and resetting NSURLCredentialStorage, but the delegate method didReceiveAuthenticationChallenge: is never called
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];
			}
		}
	}
}
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.
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.