0

I am using Alamofire 4.5, and XCode 9.0.1. I cannot connect to my local Nginx configured with a self-signed cert.

As per this answer, I am using the following code:

private static var Manager : Alamofire.SessionManager = {
    // Create the server trust policies
    let serverTrustPolicies: [String: ServerTrustPolicy] = [
        "localhost:8443": .disableEvaluation
    ]
    // Create custom manager
    let configuration = URLSessionConfiguration.default
    configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
    let man = Alamofire.SessionManager(
        configuration: URLSessionConfiguration.default,
        serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
    )
    return man
}()

And making the call like this:

DataService.Manager.request("https://localhost:8443/foo", parameters: parameters).validate().responseJSON

I tried various configurations in my project, but to no avail:

Xcode info configuration for security

Here is the error I am seeing:

2017-10-27 08:59:17.118751-0600 hptest[53607:8423753] TIC SSL Trust 
Error [1:0x60400016e580]: 3:0
2017-10-27 08:59:17.119020-0600 hptest[53607:8423753] 
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, 
-9813)
2017-10-27 08:59:17.119111-0600 hptest[53607:8423753] Task <A8A3F1A4-
D6A5-4AD6-9C3F-23697D8B63AD>.<1> HTTP load failed (error code: -1202 

[3:-9813])
2017-10-27 08:59:17.119281-0600 hptest[53607:8423742] Task <A8A3F1A4-D6A5-4AD6-9C3F-23697D8B63AD>.<1> finished with error - code: -1202
Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “localhost” which could put your confidential information at risk." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x6000001149a0>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9813, NSErrorPeerCertificateChainKey=(
    "<cert(0x7fc41b870000) s: localhost i: localhost>"
), NSUnderlyingError=0x60800005f980 {Error Domain=kCFErrorDomainCFNetwork Code=-1202 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x6000001149a0>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9813, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9813, kCFStreamPropertySSLPeerCertificates=(
    "<cert(0x7fc41b870000) s: localhost i: localhost>"
)}}, NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “localhost” which could put your confidential information at risk., NSErrorFailingURLKey=https://localhost:8443/foo, NSErrorFailingURLStringKey=https://localhost:8443/foo, NSErrorClientCertificateStateKey=0}
Phil
  • 879
  • 2
  • 10
  • 23

1 Answers1

1

I managed to solve it with the following code for the session manager -- should have RTFM instead of SO first:

private static var Manager : Alamofire.SessionManager = {
    // Create the server trust policies
    let serverTrustPolicies: [String: ServerTrustPolicy] = [
        "localhost:8443": .disableEvaluation
    ]
    // Create custom manager
    let configuration = URLSessionConfiguration.default
    configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
    let man = Alamofire.SessionManager(
        configuration: URLSessionConfiguration.default,
        serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
    )

    man.delegate.sessionDidReceiveChallenge = { session, challenge in
        var disposition: URLSession.AuthChallengeDisposition = .performDefaultHandling
        var credential: URLCredential?

        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            disposition = URLSession.AuthChallengeDisposition.useCredential
            credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
        } else {
            if challenge.previousFailureCount > 0 {
                disposition = .cancelAuthenticationChallenge
            } else {
                credential = man.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)

                if credential != nil {
                    disposition = .useCredential
                }
            }
        }

        return (disposition, credential)
    }

    return man
}()
Phil
  • 879
  • 2
  • 10
  • 23