Authentication challenge with NSURLSession: NSURLCredentialStorage vs Keychain

687 views Asked by At

I'm trying to learn how to deal with an authentication challenge using NSURLSession. I've never previously done anything related to secure networking. I've been reading the Authentication Challenges and TLS Chain Validation section in Apple's NSURLSession Programming Guide and there the object NSURLCredentialStorage is mentioned, but in its reference I get no further description about why should I use it.

What is the difference between NSURLCredentialStorage and the Keychain? What should be the best of them to handle username and passwords securely? I've looking for an example of authentication challenge with NSURLSession and either NSURLCredentialStorage and Keychain with no success, could somebody tell me where could I find one?

Thanks in advance

1

There are 1 answers

5
Pradeep K On

If you don't want to do your own authentication for the server trust or client SSL (rarely used) you can ignore the delegate callback backs related to SSL auth callbacks and instead the system will use the default certificate chains on your keychain to authenticate the request.

If you want to do your own authentication such as verifying that the server trust is proper and if you want to do certificate pinning then you can override the didReceiveChallenge delegate callback and check the server trust explicitly.

To do certificate pinning refer https://gist.github.com/mdelete/d9dbc320d5de347c2a85

If you want to just do normal server trust check assuming that the server has certificate issued by a trusted CA that is part of the System you can use this.

OSStatus err = noErr;
BOOL trusted = NO;
NSURLProtectionSpace *  protectionSpace = challenge.protectionSpace;
SecTrustRef serverTrustRef = protectionSpace.serverTrust;
SecTrustResultType trustResult;

//check if the server trust that we got from the server can be trusted by default
err = SecTrustEvaluate(serverTrustRef, &trustResult);
trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultUnspecified));
if (trusted)
{
    [challenge.sender useCredential:[NSURLCredential credentialForTrust:protectionSpace.serverTrust]
          forAuthenticationChallenge:challenge];
}
else //if not then warn the user about this and let the user make a decision
{
     //Cancel conneciton
     [challenge.sender cancelAuthenticationChallenge:challenge];

}