HTTP Basic Authentication – Accessing Password Protected Servers

It’s not uncommon for a server to require credentials for access. A common example is a password protected directory on a web-server that will prompt for a username and password before allowing access.

When using a NSURLRequest object to access a server, the delegate methods of NSURLConnection offer a means to be notified when an authentication challenge has been requested.

This post will show one approach for managing URL requests that require authentication.

Initiate the URL Request
/*---------------------------------------------------------------------------
* Begin the authentication process 
*--------------------------------------------------------------------------*/
- (void)startAuthentication
{
  NSURL *url = [NSURL URLWithString:@"http://protectedURL.com"];
  NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
 
  // Start the connection request
  // Assumes NSURLConnection *urlConnection is defined as an
  // instance variable
   urlConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
}
Answer Authentication Challenge

If an authentication challenge is returned from the URL request, the method below will be called. To respond to the challange, create a NSURLCredential object, setting the username and password.

Notice that we can check to see how many times the challenge/response has failed and present an error message as needed.

/*---------------------------------------------------------------------------
* Received a server challenge
*--------------------------------------------------------------------------*/
- (void)connection:(NSURLConnection *)connection 
      didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
  // Access has failed two times...
  if ([challenge previousFailureCount] > 1)
  {
    [urlConnection release];
 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Authentication Error"
                                     message:"Too many unsuccessul login attempts." 
                                     delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
 
    [alert show];
    [alert release];
  }
  else 
  {
    // Answer the challenge
    NSURLCredential *cred = [[[NSURLCredential alloc] initWithUser:@"admin" password:@"password"
       persistence:NSURLCredentialPersistenceForSession] autorelease];
    [[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
  }
}
 
/*---------------------------------------------------------------------------
* Finished loading URL
*--------------------------------------------------------------------------*/
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
  NSLog(@"Connection success.");  
 
  [urlConnection release];
}
 
/*---------------------------------------------------------------------------
* URL connection fail
*--------------------------------------------------------------------------*/
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
  NSLog(@"Connection failure.");
 
  [urlConnection release];
}
  1. Hi,

    I am using code in my project. This works with Xcode 3.2 iOS 4.3 but not with Xcode 4.2 iOS 5. Can you please help.

    Thanks in advance.

    • You need not to let the “release” call in iOS 5.

Comments are closed.