NSURLSession with client certificate?

Hi,


I need to access a server via HTTPS that requires a client certificate. I have never done this before. I assume that the certificate file can somehow be associated with the NSURLSession? How exactly is this done?


Thanks,

Frank

Replies

NSURLSession implements client identity support via the

NSURLAuthenticationMethodClientCertificate
authentication challenge. The session delegate receives a
urlSession(_:didReceive:completionHandler:)
callback, and it must respond to this by calling the completion handler with either a credential that resolves the challenge or some other indication as to how to procede.

Your delegate callback might look like this:

func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    switch (challenge.protectionSpace.authenticationMethod, challenge.protectionSpace.host) {
        case (NSURLAuthenticationMethodClientCertificate, "sully.local"):
            self.didReceive(clientIdentityChallenge: challenge, completionHandler: completionHandler)
        default:
            completionHandler(.performDefaultHandling, nil)
    }
}

IMPORTANT It’s critical that, if you get a challenge you weren’t expecting, you resolve that challenge with

.performDefaultHandling
.

It should then respond to the challenge with credential that references the digital identity, like this:

func didReceive(clientIdentityChallenge challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    let identity: SecIdentity = … find the right identity …
    completionHandler(.useCredential, URLCredential(identity: identity, certificates: nil, persistence: .forSession))
}

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks, I've got my code working.