Alamofire与自签证书/ ServerTrustPolicy

我想使用Alamofire通过https连接与我的服务器进行自我签名证书通信。 我的环境在本地主机上运行。 我试图连接,但是反应一直如下所示:

Success: false Response String: nil 

我用下面的代码完成了它:

 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)") } } } 

我用这行bash创build了服务器端证书:

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

我不知道我做错了什么。 帮助会很好。

###更新###

这是cURL请求。 在我看来,没有问题,还是我错了?

 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":"abc@def.com","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"}] 

###更新2 ###

抱歉回复晚了。 这里是两个debugPrints:

请求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" 

结果debugPrint:

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

###更新3 ###

这可能是ATS问题的完整错误?

 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 

您需要在创buildServerTrustPolicy字典时添加port域。

 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) ) }() 

对于迅捷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 }() 

那么你这样称呼它:

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

学分到Cnoon

我的自签名https的方法。 serverTrustPolicy是一个open类,它的serverTrustPolicy函数也是open 。 所以它可以被覆盖。

就我而言,服务器列表将来会增长。 如果我对https列表进行硬编码,则在添加新的https服务器时需要维护列表。 所以,我决定重写ServerTrustPolicyManager类来满足我的需求。

 // 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 } } 

然后,

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