views:

349

answers:

1

I have a program running on Panther, Tiger, and Leopard systems and using the following method for NSURLConnection authentication ("encodedUserPass" is the auth string with the word Basic followed by the base64-encoded user:pass)

[theRequest addValue:encodedUserPass forHTTPHeaderField:@"Authorization"];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

...later...in didReceiveAuthenticationChallenge

if ([challenge previousFailureCount] == 0) {
NSURLCredential *newCredential;
newCredential=[NSURLCredential credentialWithUser:login_name password:password persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
}

This works perfectly fine on Panther and Leopard systems but fails utterly on Tiger. It is odd, though, that even on Panther and Leopard "didReceiveAuthenticationChallenge" is usually called (i.e., setting the headers manually seems not to work).

On Tiger, didReceiveAuthenticationChallenge is always called, tries to respond as shown above, and is then called again with failure.

Two questions: (i) Why doesn't setting the headers manually work? and (2) Why does the method shown above fail on Tiger (10.4)?

LATER UPDATE:

After some thought, I realized that there had to be something wrong with my base64-encoding method, and there was: I didn't append equals signs to bring the base64 string up to a multiple of 4 characters. I solved it with

while ([bareString length] % 4) [bareString appendString:@"="];

And now the program works on all three platforms. So question (i) is answered: setting the headers manually didn't work because I wasn't padding with equals signs.

Question (ii) remains, though: why can't I use didReceiveAuthenticationChallenge successfuly in Tiger?

A: 

I have just stumbled into the same problem that you describe, and found that NSURLCredentialPersistenceNone simply does not work on Tiger, whereas specifying NSURLCredentialPersistenceForSession does.

Depending on your application that may or may not be an acceptable workaround.

Apple's documentation leaves a bit to be desired as it doesn't specify what the scope of a 'session' actually is - until the application quits, maybe?

Nick Dowell
Thanks for this, Nick. I can imagine that this might be the explanation--perhaps it was critical to get the basic auth right because otherwise preserved NSURLCredentials were being used--instead of the ones I supplied in didReceiveAuthenticationChallenge. Would a persistent credential override one that I supplied myself in didReceiveAuthenticationChallenge?
Dennis
If there is a valid NSURLCredentials in the credential store, then didReceiveAuthenticationChallenge is not called - so in effect stored ones take precedence.
Nick Dowell