Отсутствует sessionDidReceiveChallenge в делегате Alamofire 5 - PullRequest
1 голос
/ 26 мая 2020

Мне нужно перейти с Alamofire 4 на 5, но мне не хватает sessionDidReceiveChallenge обратного вызова для делегата

Я использовал раньше в версии 4 что-то вроде этого:

let manager = Alamofire.SessionManager(
    configuration: URLSessionConfiguration.default
)

manager.delegate.sessionDidReceiveChallenge = { session, challenge in

    let method = challenge.protectionSpace.authenticationMethod

    if method == NSURLAuthenticationMethodClientCertificate {
        return (.useCredential, self.cert.urlCredential())
    }
    if method == NSURLAuthenticationMethodServerTrust {
        let trust = challenge.protectionSpace.serverTrust!
        let credential = URLCredential(trust: trust)
        return (.useCredential, credential)
    }
    return (.performDefaultHandling, Optional.none)
}

но теперь версия 5, делегат изменился на класс SessionDelegate без предоставления аналогичной функции

Я попытался использовать делегата из URLSession вот так:

let delegate = SomeSessionDelegate()

let delegateQueue: OperationQueue = .init()

delegateQueue.underlyingQueue = .global(qos: .background)

let session = URLSession(
    configuration: URLSessionConfiguration.af.default,
    delegate: delegate,
    delegateQueue: delegateQueue
)

let manager = Alamofire.Session(
    session: session,
    delegate: SessionDelegate(),
    rootQueue: .global(qos: .background)
)

class SomeSessionDelegate: NSObject, URLSessionDelegate {

    let cert = ...

    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {

        //same impl as before
    }
}

Я предположение, что моя реализация в версии 5 неверна, потому что я перестал получать обратный вызов ответа

Пожалуйста, посоветуйте, как правильно управлять запросом в версии 5

Ответы [ 2 ]

0 голосов
/ 03 июня 2020

Для обработки сертификата на уровне сеанса я использовал URLProtectionSpace в URLCredentialStorage общем хранилище, а затем установил для него Alamofire.Session конфигурацию

вот пример его настройки (порт 443 может хватит)

fileprivate func registerURLCredential() {

    let storage = URLCredentialStorage.shared

    do {
        let credential: URLCredential = try loadURLCredential("certificate", password: "blablabla")

        let url = URL.API
        let host = url.host ?? ""

        let ports: [Int] = [80, 443, url.port ?? 0]

        for port in ports {

            let space = URLProtectionSpace(
                host: host,
                port: port,
                protocol: url.scheme,
                realm: nil,
                authenticationMethod: NSURLAuthenticationMethodClientCertificate
            )

            storage.set(credential, for: space)
        }
    } catch {
        print(error)
    }
}


fileprivate func createSession(_ configurationHandler: ((_ configuration: URLSessionConfiguration) -> Void)? = nil) -> Alamofire.Session {

    let configuration = URLSessionConfiguration.af.default

    registerURLCredential()

    configuration.urlCredentialStorage = .shared

    configurationHandler?(configuration)

    let session = Session(
        configuration: configuration,
        requestQueue: .global(qos: .background),
        serializationQueue: .global(qos: .background)
    )

    return session
}

Простое использование для чего хотелось бы:

let sesstion = createSession({ configuration in

    configuration.httpMaximumConnectionsPerHost = 1
})
0 голосов
/ 27 мая 2020

Нет необходимости переопределять SessionDelegate для использования клиентских сертификатов. Alamofire будет автоматически использовать прикрепленный URLCredential для проверки сертификата клиента. Просто прикрепите учетные данные к запросу:

AF.request(...)
    .authenticate(with: clientCertCredential)
    .response...

Кроме того, проверка доверия вашего сервера вернет любое доверие как действительное, что может быть проблемой безопасности. Я бы немедленно прекратил использовать этот код.

...