2016-02-24 3 views
1

Этот код попытки и не удается получить доступ к URL SSL, который работает в браузере:Swift SSL ошибка самоподписывающемуся сертификату

let path = "https://localhost:8443/greeting" 
let request = NSMutableURLRequest(URL: NSURL(string: path)!) 
let session = NSURLSession.sharedSession() 

let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in 
    let json:JSON = JSON(data: data!) 
    if let c = json["content"].string { 
     print(c) 
    } 
}) 
task.resume() 

завершается с ошибкой:

Optional(Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=,

Что требуется, чтобы приложение, чтобы принять этот сертификат?

Этот сертификат подписан сам. Прочтите несколько решений о SO без успеха.

Запуск Xcode 7.2

+0

ли вы доверять сертификат? Как в этом вопросе https://stackoverflow.com/questions/19507207/how-do-i-accept-a-self-signed-ssl-certificate-using-ios-7s-nsurlsession-and-its – skyline75489

+2

Это проблема ATS? Пожалуйста, проверьте ваш plist. http://stackoverflow.com/a/32955793/3202193 –

+0

@ skyline75489 - Я попробовал - обновил вопрос. –

ответ

3

@Ashish Kakkad был на месте. Это работает:

class Blah: NSURLSessionDelegate { 

func rest() { 
    let path = "https://localhost:8443/greeting" 
    let request = NSMutableURLRequest(URL: NSURL(string: path)!) 
    let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() 
    let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue:NSOperationQueue.mainQueue()) 
    let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in 
     let json:JSON = JSON(data: data!) 
     if let c = json["content"].string { 
      print(c) 
     } 
    }) 
    task.resume() 
} 

func URLSession(session: NSURLSession, task: NSURLSessionTask, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) { 
     completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)) 
} 

При этом в файле Info.plist:

<key>NSAppTransportSecurity</key> 
<dict> 
    <key>NSExceptionDomains</key> 
    <dict> 
     <key>localhost</key> 
     <dict> 
      <key>NSExceptionAllowsInsecureHTTPLoads</key> 
      <true/> 
     </dict> 
    </dict> 
</dict> 
+2

Это работает, но это только обходное решение. Также обратите внимание, что Исключения, сделанные с ATS, скоро будут устаревать. – midori

+0

Я также получил новости от других разработчиков .. что яблоко не разрешает приложениям в магазине приложений с этой настройкой. – Relsell

1

вы можете использовать свои собственные сертификаты, а не мои сертификаты (fullchain.pem)

class AccessingServer: NSObject,URLSessionDelegate { 

    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { 

     if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { 
      // First load our extra root-CAs to be trusted from the app bundle. 
      let trust = challenge.protectionSpace.serverTrust 

      let rootCa = "fullchain" 
      if let rootCaPath = Bundle.main.path(forResource: rootCa, ofType: "pem") { 
       if let rootCaData = NSData(contentsOfFile: rootCaPath) { 

        let rootCert = SecCertificateCreateWithData(nil, rootCaData) 

        // let certArrayRef = CFArrayCreate(nil, UnsafeMutablePointer<UnsafePointer<Any>>([rootCert]), 1, nil) 

        SecTrustSetAnchorCertificates(trust!, rootCert as! CFArray) 

        SecTrustSetAnchorCertificatesOnly(trust!, false) 
       } 
      } 

      var trustResult: SecTrustResultType = SecTrustResultType.invalid 
      SecTrustEvaluate(trust!, &trustResult) 

      if (trustResult == SecTrustResultType.unspecified || 
       trustResult == SecTrustResultType.proceed) { 
       // Trust certificate. 

       let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!) 
       challenge.sender?.use(credential, for: challenge) 

      } else { 
       NSLog("Invalid server certificate.") 
       challenge.sender?.cancel(challenge) 
      } 
     } else { 
      NSLog("Got unexpected authentication method \(challenge.protectionSpace.authenticationMethod)"); 
      challenge.sender?.cancel(challenge) 
     } 
    } 

    } 
Смежные вопросы