2016-08-22 1 views
0

Я хотел бы реализовать клиента в Swift, используя NSURLSession, который обращается к собственному серверу компании с помощью HTTPS. Этот сертификат сервера действителен, но подписан компанией CA.Как реализовать `URLSession: didReceiveChallenge: completeHandler:` С собственными сертификатами привязки в Swift?

Как правильно использовать URLSession:didReceiveChallenge:completionHandler: в Swift?

ответ

0

Сначала вам нужно преобразовать CA-сертификат в формате DER и добавить его в качестве ресурса связки в ваш проект. В этом примере этот файл называется company_ca.der.

Далее вы готовите свойство с массивом для ЦА сертификатов в своем классе:

private var anchorCertificates = NSMutableArray() 

В инициализации загружаемой, конвертировать и добавить сертификат CA:

let caCertData = NSData(contentsOfURL: NSBundle.mainBundle().URLForResource("company_ca", withExtension: "der")!)! 
let caCert = SecCertificateCreateWithData(nil, caCertData)! 
anchorCertificates.addObject(caCert) 

Делегат обработчик будет выглядеть так:

func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) { 
    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { 
     var trust: SecTrustRef = challenge.protectionSpace.serverTrust! 
     // Make sure we accept the given hostname/ip address for the certificate 
     let serverHost = challenge.protectionSpace.host 
     let sslPolicy = SecPolicyCreateSSL(true, serverHost) 
     let sslPolicyArray = NSMutableArray() 
     sslPolicyArray.addObject(sslPolicy) 
     // Copy the existing certificates from the trust object 
     let trustCertificateArray = NSMutableArray() 
     let trustCertificateCount = SecTrustGetCertificateCount(trust) 
     for i in 0..<trustCertificateCount { 
      trustCertificateArray.addObject(SecTrustGetCertificateAtIndex(trust, i)!) 
     } 
     // Replace the trust object 
     var newTrust: SecTrustRef? 
     if SecTrustCreateWithCertificates(trustCertificateArray, sslPolicyArray, &newTrust) != errSecSuccess { 
      // application error 
      completionHandler(.CancelAuthenticationChallenge, nil) 
      return 
     } 
     trust = newTrust! 
     // Set our own anchor certificates to the trust. 
     if SecTrustSetAnchorCertificates(trust, anchorCertificates) != errSecSuccess { 
      // Application error. 
      completionHandler(.CancelAuthenticationChallenge, nil) 
      return 
     } 
     // No keychains should be searched. 
     if SecTrustSetKeychains(trust, []) != errSecSuccess { 
      print("Failed to set no keychain for the trust.") 
      completionHandler(.CancelAuthenticationChallenge, nil) 
      return 
     } 
     // Allow implicit anchors. 
     if SecTrustSetOptions(trust, .ImplicitAnchors) != errSecSuccess { 
      // Application error. 
      completionHandler(.CancelAuthenticationChallenge, nil) 
      return 
     } 
     completionHandler(.UseCredential, NSURLCredential(forTrust: trust)) 
    } else { 
     // Handle any other case. 
     completionHandler(.CancelAuthenticationChallenge, nil) 
    } 
} 
Смежные вопросы