Mac OS X Reference Library Apple Developer
Search

Authentication Challenges

An NSURLRequest object often encounters an authentication challenge, or a request for credentials from the server it is connecting to. The delegates for NSURLConnection and NSURLDownload can be notified when their request encounters an authentication challenge, so that they can act accordingly.

Deciding How to Respond to an Authentication Challenge

If an NSURLRequest object requires authentication, the delegate of the NSURLConnection (or NSURLDownload) object associated with the request first receives a connection:canAuthenticateAgainstProtectionSpace: (or download:canAuthenticateAgainstProtectionSpace:) message. This allows the delegate to analyze properties of the server, including its protocol and authentication method, before attempting to authenticate against it. If your delegate is not prepared to authenticate against the server’s protection space, you can return NO, and the system attempts to authenticate with information from the user’s keychain.

Note: If your delegate does not implement the connection:canAuthenticateAgainstProtectionSpace: method and the protection space uses client certificate authentication or server trust authentication, the system behaves as if you returned NO. The system behaves as if you returned YES for all other authentication methods.

If your delegate returns YES from connection:canAuthenticateAgainstProtectionSpace: or doesn’t implement it, and there are no valid credentials available, either as part of the requested URL or in the shared NSURLCredentialStorage, the delegate receives a connection:didReceiveAuthenticationChallenge: message. In order for the connection to continue, the delegate has three options:

To help determine the correct course of action, the NSURLAuthenticationChallenge instance passed to the method contains information about what triggered the authentication challenge, how many attempts were made for the challenge, any previously attempted credentials, the NSURLProtectionSpace that requires the credentials, and the sender of the challenge.

If the authentication challenge has tried to authenticate previously and failed, you can obtain the attempted credentials by calling proposedCredential on the authentication challenge. The delegate can then use these credentials to populate a dialog that it presents to the user.

Calling previousFailureCount on the authentication challenge returns the total number of previous authentication attempts, including those from different authentication protocols. The delegate can provide this information to the end user, to determine whether the credentials it supplied previously are failing, or to limit the maximum number of authentication attempts.

Responding to an Authentication Challenge

The following are the three ways you can respond to the connection:didReceiveAuthenticationChallenge: delegate method.

Providing Credentials

To attempt to authenticate, the application should create an NSURLCredential object with authentication information of the form expected by the server. You can determine the server’s authentication method by calling authenticationMethod on the protection space of the provided authentication challenge. Some authentication methods supported by NSURLCredential are:

HTTP Basic Authentication (NSURLAuthenticationMethodHTTPBasic)

The basic authentication method requires a user name and password. Prompt the user for the necessary information and create an NSURLCredential object with credentialWithUser:password:persistence:.

HTTP Digest Authentication (NSURLAuthenticationMethodHTTPDigest)

Like basic authentication, digest authentication just requires a user name and password (the digest is generated automatically). Prompt the user for the necessary information and create an NSURLCredential object with credentialWithUser:password:persistence:.

Client Certificate Authentication (NSURLAuthenticationMethodClientCertificate)

Client certificate authentication requires the system identity and all certificates needed to authenticate with the server. Create an NSURLCredential object with credentialWithIdentity:certificates:persistence:.

Server Trust Authentication (NSURLAuthenticationMethodServerTrust)

Server trust authentication requires a trust provided by the protection space of the authentication challenge. Create an NSURLCredential object with credentialForTrust:.

After you’ve created the NSURLCredential object, pass it to the authentication challenge’s sender with useCredential:forAuthenticationChallenge:.

Continuing Without Credentials

If the delegate chooses not to provide a credential for the authentication challenge, it can attempt to continue without one by calling continueWithoutCredentialsForAuthenticationChallenge: on [challenge sender]. Depending on the protocol implementation, continuing without credentials may either cause the connection to fail, resulting in a connectionDidFailWithError: message, or return alternate URL contents that don’t require authentication.

Canceling the Connection

The delegate may also choose to cancel the authentication challenge by calling cancelAuthenticationChallenge: on [challenge sender]. The delegate receives a connection:didCancelAuthenticationChallenge: message, providing the opportunity to give the user feedback.

The implementation shown in Listing 1 attempts to authenticate the challenge by creating an NSURLCredential instance with a user name and password supplied by the application’s preferences. If the authentication has failed previously, it cancels the authentication challenge and informs the user.

Listing 1  An example of using the connection:didReceiveAuthenticationChallenge: delegate method

-(void)connection:(NSURLConnection *)connection
        didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if ([challenge previousFailureCount] == 0) {
        NSURLCredential *newCredential;
        newCredential = [NSURLCredential credentialWithUser:[self preferencesName]
                                                 password:[self preferencesPassword]
                                              persistence:NSURLCredentialPersistenceNone];
        [[challenge sender] useCredential:newCredential
               forAuthenticationChallenge:challenge];
    } else {
        [[challenge sender] cancelAuthenticationChallenge:challenge];
        // inform the user that the user name and password
        // in the preferences are incorrect
        [self showPreferencesCredentialsAreIncorrectPanel:self];
    }
}

If the delegate doesn’t implement connection:didReceiveAuthenticationChallenge: and the request requires authentication, valid credentials must already be available in the URL credential storage or must be provided as part of the requested URL. If the credentials are not available or if they fail to authenticate, a continueWithoutCredentialForAuthenticationChallenge: message is sent by the underlying implementation.




Last updated: 2010-03-24

Did this document help you? Yes It's good, but... Not helpful...