I have the following code (swift implementation):
func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace) -> Bool
{
return protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
}
func connection(connection: NSURLConnection, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge)
{
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
{
if challenge.protectionSpace.host == "myDomain"
{
let credentials = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)
challenge.sender.useCredential(credentials, forAuthenticationChallenge: challenge)
}
}
challenge.sender.continueWithoutCredentialForAuthenticationChallenge(challenge)
}
It works perfectly in iOS 8.x, but does not work iOS 7.x In iOS 7.x I have error:
NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
Any idea? thank you!!!
If you want to turn on SSL/TLS trust for that certificate, go to Settings > General > About > Certificate Trust Settings. Under "Enable full trust for root certificates," turn on trust for the certificate. Apple recommends deploying certificates via Apple Configurator or Mobile Device Management (MDM).
Navigate to the site with the cert you want to trust, and click through the usual warnings for untrusted certificates. In the address bar, right click on the red warning triangle and "Not secure" message and, from the resulting menu, select "Certificate" to show the certificate.
Import the self-signed certificate to the client Windows computer. On the Windows computer, start MMC (mmc.exe). Add the Certificates snap-in for the computer account and manage certificates for the local computer. Import the self-signed certificate into Trusted Root Certification Authorities > Certificates.
Both connection:canAuthenticateAgainstProtectionSpace:
and connection:didReceiveAuthenticationChallenge:
are deprecated in iOS 8 anyway so you should use other methods.
What I am using in my projects is a delegate method of NSURLSessionDelegate. Adhere to that protocol then add this method:
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) {
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust))
}
Then, when you use initialize NSURLSession with delegate set to self. For example:
var session = NSURLSession(configuration: configuration, delegate: self, delegateQueue:NSOperationQueue.mainQueue())
Then use that session instance to call dataTaskWithRequest method on:
var task = session.dataTaskWithRequest(request){
(data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
if error != nil {
callback("", error.localizedDescription)
} else {
var result = NSString(data: data, encoding:
NSASCIIStringEncoding)!
}
}
task.resume()
Complete working example can be found here.
For security reasons, if you use a self-signed certificate I recommend also implementing public key pinning (https://gist.github.com/edwardmp/df8517aa9f1752e73353)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With