Morning Everyone,
I've been attempting to write an application that does some GETs from a remote Web Service that requires authentication. My main problem is that the majority of these remote servers (and there are a lot of them) don't have valid certificates. I've got code to accept the invalid certificate and code to respond to the challenge with the correct uname & pass (below). The problem I'm having is getting the two to play together. I can't seem to find a way to send the challenge both NSURLCredential
s or a way to chain the callbacks correctly. When I try to chain them I can't get my NSURLRequest
to call didReceiveAuthenticationChallenge
twice.
Any thoughts would be appreciated!
Code for Authentication...
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if(!hasCanceled){
if ([challenge previousFailureCount] == 0) {
NSURLCredential *newCredential;
newCredential=[NSURLCredential credentialWithUser:_username password:_password persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
}
else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
NSLog(@"Bad Username Or Password");
badUsernameAndPassword = YES;
finished = YES;
}
}
}
You can only reply to an NSURLAuthenticationChallenge
with a credential for that challenge. You can determine what type of challenge you've received using:
[[challenge protectionSpace] authenticationMethod]
The possible values are documented here. In the case of an invalid server certificate, the authentication method will be NSURLAuthenticationMethodServerTrust
. In your code, you should check the authentication method and respond appropriately.
if ([challenge previousFailureCount] > 0) {
// handle bad credentials here
[[challenge sender] cancelAuthenticationChallenge:challenge];
return;
}
if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodServerTrust) {
// check if the user has previously accepted the certificate, otherwise prompt
} else if ([[challenge protectionSpace] authenticationMethod] == /* your supported authentication method here */) {
[[challenge sender] useCredential:/* your user's credential */ forAuthenticationChallenge:challenge];
}
It's not an error if you don't get both authentication challenges each time. You can cache credentials when you create them. If you do, you won't necessarily be prompted again.
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