HTTP Basic Authentication – Accessing Password Protected Servers

Wed, Aug 25

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];
}

3 comments

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.

by Sumit on Nov 10, 2011. Reply #

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

by Test on Jan 14, 2013. Reply #

Works Fins. Nice explanation

by Muthukumar on Sep 13, 2012. Reply #

Leave a Comment