Official info from Apple suggest creation of a certificate which means changes in server side which is not an option in my case.
Below I setup my app so requests can be done with an insecure certificate only to my server. This should be done only for development/testing purposes and should not be in production
1. Instruct ATS to ignore your server
EditInfo.plist to have this (From Lory Lory in Stackoverflow):
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>self-signed-certificate.server.com</key>
        <dict>
            <!--Include to allow subdomains too-->
            <key>NSIncludesSubdomains</key>
            <true/>
            <!--Include to allow ssl requests with self signed certificates and other insecure stuff-->
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>
NSAppTransportSecurity can be found in InfoPlistKeyReference - CocoaKeys. Beware that key names are not even correct, see NSExceptionAllowsInsecureHTTPLoads, instead of NSTemporaryExceptionAllowsInsecureHTTPLoads, etc.
2. Make sure challenge is fulfilled in the WKWebView
If you are using WKWebView then you need to implement the navigation delegate. Remember, at least you should have a naive filter like below. Accepting everything is much more dangerous. This should be done only for testing/developing purposes.func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) {
    if challenge.protectionSpace.host == "self-signed-certificate.server.com" {
        let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
        completionHandler(.useCredential, credential)
    } else {
        completionHandler(.performDefaultHandling, nil)
    }
}
webView = WKWebView()
webView.frame = CGRect(x: 0, y: 0, width: w, height: h)
webView.navigationDelegate = self
let request = URLRequest(url: URL(string: "https://self-signed-certificate.server.com")!)
webView.load(request)
3. Make sure challenge is fulfilled in the NSURLSession
If you are using the standard NSURLSession APIs then implement NSURLSessionDelegate method as below:func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
     // Pass test server with self signed certificate
    if challenge.protectionSpace.host == "self-signed-certificate.server.com" {
        completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
    } else {
        completionHandler(.performDefaultHandling, nil)
    }
}let session = NSURLSession(
      configuration: NSURLSessionConfiguration.default,
      delegate: object, // DO NOT FORGET YOUR OBJECT HERE!!
      delegateQueue: nil)
let url = URL(string: "https://self-signed-certificate.server.com")!
let task = session.dataTask(with: url) { (data, response, error) in
    ...
}
task.resume()3. Make sure challenge is fulfilled in Alamofire
If you are using Alamofire (one famous library wrapper for NSURLSession + some goodies) then implement something very similar as above.let sessionManager = SessionManager()
sessionManager.delegate.taskDidReceiveChallengeWithCompletion = { (_, _, challenge, completionHandler) -> Void in
    // Pass test server with self signed certificate
    if challenge.protectionSpace.host == "self-signed-certificate.server.com" {
        completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
    } else {
        completionHandler(.performDefaultHandling, nil)
    }
}
sessionManager.request("https://self-signed-certificate.server.com", method: .get).response { response in 
 ...
}

 
 
0 comments :
Post a Comment