Reputation: 681
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]];
}
}
Upvotes: 0
Views: 2821
Reputation: 18477
You should use a different delegate callback, connection:didReceiveAuthenticationChallenge:
.
- (void) connection:(NSURLConnection *)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if ([challenge previousFailureCount] > 0) {
// Do something, like prompt for credentials or cancel the connection
} else {
NSURLCredential *creds = [NSURLCredential
credentialWithUser:@"someUser"
password:@"somePassword"
persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:creds forAuthenticationChallenge:challenge];
}
}
Upvotes: 3