Swift: how to request a url with a self-signed certificate?

I am opening an SSL connection to retrieve JSON in Swift, but I am testing my own server with a self-signed certificate. Here is a snippet of the URL request:

var urlPath = "https://myhost.com/get_json" var url: NSURL = NSURL(string: urlPath) var request: NSURLRequest = NSURLRequest(URL: url) var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false) connection.start() 

However, it gets rejected (correctly) due to the certificate:

 Opening connection to https://myhost.com/get_json 2014-06-05 09:37:02.543 AppName[44835:3182593] NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) Connection failed.The certificate for this server is invalid. You might be connecting to a server that is pretending to be "myhost.com" which could put your confidential information at risk.## Heading ## 
+6
source share
3 answers

You need these additional methods from NSURLConnectionDelegate :

 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 == "www.myhost.com" { let credentials = NSURLCredential(forTrust: challenge!.protectionSpace.serverTrust) challenge!.sender.useCredential(credentials, forAuthenticationChallenge: challenge) } } challenge?.sender.continueWithoutCredentialForAuthenticationChallenge(challenge) } 

NOTE: This is only possible using the asynchronous NSURLConnection .

+5
source

This is my solution for Swift3

 let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main) extension WebServiceManager : URLSessionDelegate { func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { var trustedHostArray = [String]() if Utils.getEnviroment() == Constants.Environment.Production.rawValue { trustedHostArray = Constants.TRUSTED_HOSTS.Production } else { trustedHostArray = Constants.TRUSTED_HOSTS.Develop } if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { if trustedHostArray.contains(challenge.protectionSpace.host) { let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!) challenge.sender?.use(credential, for: challenge) completionHandler(URLSession.AuthChallengeDisposition.useCredential, credential) } } } } 
0
source

I updated Eric's answer for Swift 3:

 func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: URLProtectionSpace?) -> Bool { return protectionSpace?.authenticationMethod == NSURLAuthenticationMethodServerTrust } func connection(connection: NSURLConnection, didReceiveAuthenticationChallenge challenge: URLAuthenticationChallenge?) { if challenge?.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { if challenge?.protectionSpace.host == "www.myhost.com" { let credentials = URLCredential(trust: challenge!.protectionSpace.serverTrust!) challenge!.sender?.use(credentials, for: challenge!) } } challenge?.sender?.continueWithoutCredential(for: challenge!) } 
0
source

Source: https://habr.com/ru/post/970398/


All Articles