Alamofire 5替代sessionDidReceiveChallenge。

问题描述 投票:0回答:1

我刚刚转到Alamofire 5。

之前我使用URLSession和 證書製造商 和处理认证挑战,我使用了委托方法的 URLSessionDelegate 与哈希值

func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge,
                completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    print("being challanged! for \(challenge.protectionSpace.host)")
    guard let trust = challenge.protectionSpace.serverTrust else {
        print("invalid trust!")
        completionHandler(.cancelAuthenticationChallenge, nil)
        return
    }

    let credential = URLCredential(trust: trust)

    let pinner = setupCertificatePinner(host: challenge.protectionSpace.host)

    if (!pinner.validateCertificateTrustChain(trust)) {
        print("failed: invalid certificate chain!")
        challenge.sender?.cancel(challenge)
    }

    if (pinner.validateTrustPublicKeys(trust)) {
        completionHandler(.useCredential, credential)
    } else {
        didPinningFailed = true
        print("couldn't validate trust for \(challenge.protectionSpace.host)")
        completionHandler(.cancelAuthenticationChallenge, nil)
    }

}

搬到Alamofire 5后,没有方法。sessionDidReceiveChallenge 这在早期版本中是可用的。

我试过了。

private let session: Session = {
    let manager = ServerTrustManager(allHostsMustBeEvaluated: true, evaluators:
        ["devDomain.com": DisabledTrustEvaluator(),
         "prodDomain.com": PublicKeysTrustEvaluator()])
    let configuration = URLSessionConfiguration.af.default

    return Session(configuration: configuration, serverTrustManager: manager)
}()

但我收到错误信息

Error Domain=Alamofire.AFError Code=11 "Server trust evaluation failed due to reason: No public keys were found or provided for evaluation."

更新。我还是更喜欢只用256个指纹来解析它,因为我们在第一次调用api时就会得到域名和它的哈希值。

ios swift https alamofire
1个回答
1
投票

首先你需要一个 ServerTrustEvaluating 处理证书引脚的一个简单的实现是类似于

public final class CertificatePinnerTrustEvaluator: ServerTrustEvaluating {

    public init() {}

    func setupCertificatePinner(host: String) -> CertificatePinner {

        //get the CertificatePinner
    }

    public func evaluate(_ trust: SecTrust, forHost host: String) throws {

        let pinner = setupCertificatePinner(host: host)

        if (!pinner.validateCertificateTrustChain(trust)) {
            print("failed: invalid certificate chain!")
            throw AFError.serverTrustEvaluationFailed(reason: .noCertificatesFound)
        }

        if (!pinner.validateTrustPublicKeys(trust)) {
            print ("couldn't validate trust for \(host)")

            throw AFError.serverTrustEvaluationFailed(reason: .noCertificatesFound)
        }
    }
}

为了能够使用相同的评估器,我建议将其子类化为 ServerTrustManager 为了返回相同的评估器,我是这样做的。

class CertificatePinnerServerTrustManager: ServerTrustManager {

    let evaluator = CertificatePinnerTrustEvaluator()

    init() {
        super.init(allHostsMustBeEvaluated: true, evaluators: [:])
    }

    open override func serverTrustEvaluator(forHost host: String) throws -> ServerTrustEvaluating? {

        return evaluator
    }
}

然后你应该准备好了 通过创建会话并将管理器传递给它

private let session: Session = {

    let trustManager = CertificatePinnerServerTrustManager()

    return Session(serverTrustManager: trustManager)
}()

我参考的是方法 urlSession(_:task:didReceive:completionHandler:) 在Alamofire源码中的SessionDelegate.swift第86行(Alamofire V5.2.1)。


0
投票

如果你想用公钥引脚,你需要在你的应用程序的bundle中提供证书来解析这些公钥,或者以其他方式将它们提供到 PublicKeysTrustEvaluator.

© www.soinside.com 2019 - 2024. All rights reserved.