I’m trying to get my iOS app to access files from my local apache server using basic authentication. Everything works fine from the browser and I have to enter my username and password to access an image in the restricted folder. However in the app some strange things are happening.
I make an NSURLConnection to the server (which is all working fine) and the first time my request is made the delegate method - (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge is called. For test purposes I respond with an empty NSURLCredential and obviously the connection fails. However when I make the request again the delegate method isn’t called and somehow the image gets downloaded and displayed without any authentication. I’m really confused as to what’s going on!
Here is some of the code:
- (IBAction)loginPressed
{
self.username = self.usernameField.text;
self.password = self.passwordField.text;
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://192.168.0.2/secret/favicon.ico"]];
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data
{
[self.data appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
self.imageView.image = [UIImage imageWithData:self.data];
self.errorLabel.text = @"";
}
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge previousFailureCount] == 0) {
NSURLCredential *newCredential = [NSURLCredential credentialWithUser:self.username password:self.password persistence:NSURLCredentialPersistenceNone];
[challenge.sender useCredential:newCredential forAuthenticationChallenge:challenge];
} else {
[challenge.sender cancelAuthenticationChallenge:challenge];
self.errorLabel.text = @"Invalid Username and/or Password";
self.imageView.image = [UIImage imageWithData:[[NSData alloc] init]];
}
}
You should use a different delegate callback,
connection:didReceiveAuthenticationChallenge:.