Rupert Horlick
Rupert Horlick

Reputation: 681

iOS seems to be bypassing basic server authentication

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

Answers (1)

Wayne Hartman
Wayne Hartman

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

Related Questions