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
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
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.