如何使用Alamofire 1.3连接到自签名服务器

时间:2015-08-11 14:50:19

标签: swift alamofire

连接到自签名服务器时出现以下错误。

错误域= NSURLErrorDomain代码= -1202"此服务器的证书无效。您可能连接到假装为“maskeddomain.com”的服务器,这可能会使您的机密信息面临风险。" UserInfo = 0x7fb6dec259e0 {NSURLErrorFailingURLPeerTrustErrorKey =,NSLocalizedRecoverySuggestion =您是否还要连接到服务器?,_kCFStreamErrorCodeKey = -9813,NSUnderlyingError = 0x7fb6dbe0dd90"操作无法完成。 (kCFErrorDomainCFNetwork错误-1202。)"

看起来Alamofire 1.3(https://github.com/Alamofire/Alamofire#security)允许禁用此验证。有没有人实现过这个?我在我的快速项目中使用了Alamofire API,并不知道究竟在哪里"服务器信任策略管理器"需要实施。请指教。

5 个答案:

答案 0 :(得分:36)

Swift 3 Swift 4 Alamofire 4 的管理员配置:

private static var manager: Alamofire.SessionManager = {

    // Create the server trust policies
    let serverTrustPolicies: [String: ServerTrustPolicy] = [
        "test.example.com": .disableEvaluation
    ]

    // Create custom manager
    let configuration = URLSessionConfiguration.default
    configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
    let manager = Alamofire.SessionManager(
        configuration: URLSessionConfiguration.default,
        serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
    )

    return manager
}()

答案 1 :(得分:22)

有一种方法可以更改Alamofire管理器共享实例的服务器信任策略,但不建议这样做。相反,您应该创建自己的经理自定义实例。以下是推荐的解决方案,代码 Swift 2.0 ,来自 swift-2.0分支的Alamofire,编译在 Xcode7 beta 5

创建经理的自定义实例

因为您不会在Alamofire上使用请求方法,而是使用自定义管理器上的请求方法,您需要考虑存储管理器的位置。我所做的是将它作为静态存储在我的网络包装器中(利用Alamofire并处理我的应用程序网络需求的类)。我这样设置:

private static var Manager : Alamofire.Manager = {
        // Create the server trust policies
        let serverTrustPolicies: [String: ServerTrustPolicy] = [
            "maskeddomain.com": .DisableEvaluation
        ]
        // Create custom manager
        let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
        configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders
        let man = Alamofire.Manager(
            configuration: NSURLSessionConfiguration.defaultSessionConfiguration(),
            serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
        )
        return man
    }()

下一步是将您使用Alamofire.request()的所有来电切换为Manager.request(),这样您就应该这样:

Manager.request(.GET, "http://stackoverflow.com").responseJSON(
    completionHandler: { (_, respose, result) -> Void in
            if result.isSuccess {
                // enjoy your success
            } else if result.isFailure {
                // deal with your failure
            }
    })

如果您想要更改管理器的共享实例,请转至here以获取更多信息。

答案 2 :(得分:12)

README中直接发布了一个示例,演示了如果您需要这样做,将如何禁用评估。

由于您还需要创建自己的class NetworkManager { static let sharedInstance = NetworkManager() let defaultManager: Alamofire.Manager = { let serverTrustPolicies: [String: ServerTrustPolicy] = [ "test.example.com": .PinCertificates( certificates: ServerTrustPolicy.certificatesInBundle(), validateCertificateChain: true, validateHost: true ), "insecure.expired-apis.com": .DisableEvaluation ] let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders return Alamofire.Manager( configuration: configuration, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies) ) }() } 实例,因此您需要执行以下操作:

NetworkManager.sharedInstance.defaultManager

这将允许您使用a = 'sdfLKC[m2G]TO' 对象发出请求。

答案 3 :(得分:3)

我项目的另一种方法。 ServerTrustPolicyManageropen类,serverTrustPolicy函数也是open。所以它可以覆盖。

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

        // or, if `host` contains substring, return `disableEvaluation`
        // Ex: host contains `my_company.com`, then trust it.
    }
}

然后,

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

更新@ 2018,01

为了触发ServerTrustPolicyManager,需要配置项目的Info.plist。我找到了解决方案,详细at this post, cnoon's comment @ 1 Nov 2015

enter image description here

例如,如果有名为site1.foo.com的网址,site2.foo.com,.... 然后添加App Transport Security Settings - > Exception Domains - > foo.com字典,包含以下条目。

  • NSExceptionRequiresForwardSecrecy:NO
  • NSExceptionAllowsInsecureHTTPLoads:是
  • NSIncludesSubdomains:YES

More detail you can refer the post.

答案 4 :(得分:1)

无论如何,@ cnoon的答案几乎已经满了。但是我遇到了ssl验证的另一个麻烦,所以如果有人可以从中得到帮助,我想把我的代码放在这里。经理init为:

private var manager: Manager?
// Import the certificates like xxx.cer to your project(anywhere will be fine), then the ServerTrustPolicy.certificatesInBundle() can find them
let serverTrustPolicy = ServerTrustPolicy.PinCertificates(
            certificates: ServerTrustPolicy.certificatesInBundle(),
            validateCertificateChain: false,
            validateHost: true
        )
let serverTrustPolicies: [String : ServerTrustPolicy] = [
            "sub.server.com": .DisableEvaluation, // because the certificates only add the main domain, so disable evaluation for subdomain
            "192.168.0.2:8090": .DisableEvaluation, // the IP address for request data
            "www.server.com": serverTrustPolicy
        ]
manager = Manager(serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies))

然后使用经理请求:

// this function in the class which for manager the Alamofire request
public func request(method: Alamofire.Method, _ URLString: URLStringConvertible,
                        parameters: [String : AnyObject]?) -> Alamofire.Request
    {
        // we do not need use Alamofire.request now, just use the manager you have initialized
        return manager!.request(method, URLString, parameters: parameters,
                                 headers: ["tokenId": UserManager_Inst.tokenID])
    }

p.s。:它是swift 2.3样本