Alamofire带有自签名证书/ ServerTrustPolicy

tea*_*uit 21 https ios swift alamofire

我想使用Alamofire通过带有自签名证书的https连接与我的服务器通信.我的环境在localhost上运行.我试过连接,但是响应一直都是这样的:

Success: false
Response String: nil
Run Code Online (Sandbox Code Playgroud)

我用以下代码完成了它:

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

}
Run Code Online (Sandbox Code Playgroud)

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

openssl req -x509 -nodes -days 999 -newkey rsa:2048 -keyout server.key -out server.crt
Run Code Online (Sandbox Code Playgroud)

我不知道我做错了什么.帮助会很棒.

###更新###

这是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"}]
Run Code Online (Sandbox Code Playgroud)

### Update 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"
Run Code Online (Sandbox Code Playgroud)

结果debugPrint:

FAILURE: Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLKey=https://localhost:3443/message, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=https://localhost:3443/message}
Run Code Online (Sandbox Code Playgroud)

### Update 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
Run Code Online (Sandbox Code Playgroud)

cno*_*oon 15

您需要port在创建ServerTrustPolicy字典时添加域.

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)
    )
}()
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的回答.你是对的.我忘了添加端口.但是如果我添加端口,我会收到以下错误:`Message [4401:95209] NSURLSession/NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9802) (2认同)

Wil*_*aan 8

对于快速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
}()
Run Code Online (Sandbox Code Playgroud)

然后你这样称呼它:

Manager.upload(body.data(using: .utf8)!, to: url, method: .post, headers: headers)
Run Code Online (Sandbox Code Playgroud)

积分到Cnoon