2015-09-13 8 views
15

Ich möchte Alamofire verwenden, um mit meinem Server über eine https-Verbindung mit einem selbstsignierten Zertifikat zu kommunizieren. Meine Umgebung läuft auf localhost. Ich habe zu verbinden versucht, aber die Antwort die ganze Zeit sieht wie folgt aus:Alamofire mit einem selbstsignierten Zertifikat/ServerTrustPolicy

Success: false 
Response String: nil 

Ich habe es mit dem folgenden Code getan:

import Foundation 
import UIKit 
import Alamofire 

class MessageView: UITableViewController { 

    let defaultManager: Alamofire.Manager = { 
     let serverTrustPolicies: [String: ServerTrustPolicy] = [ 
      "localhost": .DisableEvaluation 
     ] 

     let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() 
     configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders 

     return Alamofire.Manager(
      configuration: configuration, 
      serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies) 
     ) 
    }() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     defaultManager 
      .request(.GET, "https://localhost:3443/message") 
      .responseJSON { _, _, result in 
       print("Success: \(result.isSuccess)") 
       print("Response String: \(result.value)") 
      } 
    } 

} 

ich die Server-Zertifikaten mit erstellt haben diese Linie der bash:

openssl req -x509 -nodes -days 999 -newkey rsa:2048 -keyout server.key -out server.crt 

ich weiß nicht, was mache ich falsch. Hilfe wäre großartig.

### aktualisieren ###

Hier ist die cURL Anfrage. Meiner Meinung nach gibt es kein Problem, oder irre ich mich?

curl -X GET https://localhost:3443/message -k -v 

* Trying ::1... 
* Connected to localhost (::1) port 3443 (#0) 
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 
* Server certificate: teawithfruit 
> GET /message HTTP/1.1 
> Host: localhost:3443 
> User-Agent: curl/7.43.0 
> Accept: */* 
> 
< HTTP/1.1 200 OK 
< Content-Type: application/json; charset=utf-8 
< Content-Length: 1073 
< Date: Tue, 15 Sep 2015 06:20:45 GMT 
< Connection: keep-alive 
< 
* Connection #0 to host localhost left intact 

[{"_id":"55f3ed2d81a334558241e2f4","email":"[email protected]","password":"abc","name":"teawithfruit","language":"en","__v":0,"timestamp":1442049325159,"messages":[{"_id":"55f40553e568236589772c61","user":"55f3ed2d81a334558241e2f4","language":"en","message":"hello world","__v":0,"timestamp":1442055507301,"id":"55f40553e568236589772c61"},{"_id":"55f48b2b02e7b059b54e99f6","user":"55f3ed2d81a334558241e2f4","language":"en","message":"hello world","__v":0,"timestamp":1442089771312,"id":"55f48b2b02e7b059b54e99f6"}],"id":"55f3ed2d81a334558241e2f4"}] 

### Update 2 ###

Sorry für die späte Antwort. Hier sind die beiden debugPrints:

Anfrage debugPrint:

$ curl -i \ 
    -H "Accept-Language: en-US;q=1.0" \ 
    -H "Accept-Encoding: gzip;q=1.0,compress;q=0.5" \ 
    -H "User-Agent: Message/com.teawithfruit.Message (1; OS Version 9.0 (Build 13A340))" \ 
    "https://localhost:3443/message" 

Ergebnis debugPrint:

FAILURE: Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLKey=https://localhost:3443/message, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=https://localhost:3443/message} 

### Update 3 ###

Dies ist die komplette Fehler mit vielleicht einem ATS-Problem?

nil 
$ curl -i \ 
    -H "Accept-Language: en-US;q=1.0" \ 
    -H "Accept-Encoding: gzip;q=1.0,compress;q=0.5" \ 
    -H "User-Agent: Message/com.teawithfruit.Message (1; OS Version 9.0 (Build 13A340))" \ 
    "https://localhost:3443/message" 
2015-10-17 15:10:48.346 Message[25531:1001269] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802) 
FAILURE: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x7fdc3044b740>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=<CFArray 0x7fdc2a7ca300 [0x10f7037b0]>{type = immutable, count = 1, values = (
    0 : <cert(0x7fdc31d31670) s: teawithfruit i: teawithfruit> 
)}, NSUnderlyingError=0x7fdc30064bd0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x7fdc3044b740>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=<CFArray 0x7fdc2a7ca300 [0x10f7037b0]>{type = immutable, count = 1, values = (
    0 : <cert(0x7fdc31d31670) s: teawithfruit i: teawithfruit> 
)}}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://localhost:3443/message, NSErrorFailingURLStringKey=https://localhost:3443/message, NSErrorClientCertificateStateKey=0} 
Success: false 
Response String: nil 
+0

Können Sie erfolgreich eine Anfrage cURL? Wenn ja, könnten Sie das cURL-Beispiel und die Ausgabe sowie "debugPrint" auf dem "Ergebnis" hinzufügen? – cnoon

+0

Ich habe den Beitrag aktualisiert. Ich kann kein Problem sehen. Machst du? – teawithfruit

+0

Könnten Sie die Ausgabe von 'debugPrint (request)' posten, wenn 'request' die' let request = defaultManager.request (...) 'ist. Könntest du auch die Ausgabe von 'debugPrint (result)' posten? Ohne diese ist es schwer zu helfen. – cnoon

Antwort

12

Sie benötigen die port Domäne hinzufügen, wenn Sie Ihr ServerTrustPolicy Wörterbuch erstellen.

let defaultManager: Alamofire.Manager = { 
    let serverTrustPolicies: [String: ServerTrustPolicy] = [ 
     "localhost:3443": .DisableEvaluation 
    ] 

    let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() 
    configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders 

    return Alamofire.Manager(
     configuration: configuration, 
     serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies) 
    ) 
}() 
+2

Vielen Dank für die Antwort. Du hast recht. Ich habe vergessen, den Port hinzuzufügen. Aber wenn ich den Port hinzufüge, erhalte ich den folgenden Fehler: 'Nachricht [4401: 95209] NSURLSession/NSURLConnection HTTP Laden fehlgeschlagen (kCFStreamErrorDomainSSL, -9802)' – teawithfruit

+0

Haben Sie vielleicht eine andere Idee? – teawithfruit

+0

Jetzt scheint es, Sie laufen in ATS. Weitere Informationen [hier] (https://forums.developer.apple.com/thread/13472). Könnten Sie die vollständigen Details des neuen Fehlers in einem Update in der Frage veröffentlichen? – cnoon

2

Mein Ansatz für selbstsignierte https. Die ServerTrustPolicyManager ist eine open Klasse, und es ist serverTrustPolicy Funktion ist open auch. So kann es überschrieben werden.

In meinem Fall wird die Serverliste in Zukunft wachsen. Wenn ich die https-Liste fest codiere, muss ich die Liste beim Hinzufügen eines neuen https-Servers pflegen. Also entscheide ich mich, die ServerTrustPolicyManager Klasse zu überschreiben, um meine Bedürfnisse zu erfüllen.

// For Swift 3 and Alamofire 4.0 
open class MyServerTrustPolicyManager: ServerTrustPolicyManager { 

    // Override this function in order to trust any self-signed https 
    open override func serverTrustPolicy(forHost host: String) -> ServerTrustPolicy? { 
     return ServerTrustPolicy.disableEvaluation 
    } 
} 

Dann

let trustPolicies = MyServerTrustPolicyManager(policies: [:]) 
    let manager = Alamofire.SessionManager(configuration: sessionConfig, delegate: SessionDelegate(), serverTrustPolicyManager: trustPolicies) 
3

Für das schnelle 4:

private static var Manager : Alamofire.SessionManager = { 
    // Create the server trust policies 
    let serverTrustPolicies: [String: ServerTrustPolicy] = [ 
     "your domain goes here": .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 
}() 

Dann sind Sie es so nennen:

Manager.upload(body.data(using: .utf8)!, to: url, method: .post, headers: headers) 

Credits to Cnoon

1

So weiß ich, einige Zeit ist vergangen, aber ich hatte genau das gleiche Problem. Und ich fand eine Lösung mit obigen Antworten. Ich hatte zwei Dinge zu trustPolicies hinzuzufügen:

let defaultManager: Alamofire.Manager = { 
    let serverTrustPolicies: [String: ServerTrustPolicy] = [ 
     // Here host with port (trustPolicy is my var where I pin my certificates) 
     "localhost:3443": trustPolicy 
     //Here without port 
     "localhost": .disableEvaluation 
    ] 

    let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() 
    configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders 

    return Alamofire.Manager(
     configuration: configuration, 
     serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies) 
    ) 
}() 

Auch in Info.plist hatte hinzuzufügen:

<key>AppTransportSecurity</key> 
<dict> 
    <key>AllowsArbitraryLoads</key> 
     <true/> 
</dict> 
Verwandte Themen