iosswiftalamofirealamofire5

Missing sessionDidReceiveChallenge in Alamofire 5 delegate


I need to migrate from Alamofire 4 to 5 but I'm missing sessionDidReceiveChallenge callback on the delegate

I used before in version 4 something like this:

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

but now is version 5 the delegate has changed to SessionDelegate class without providing a similar function

I tried to use the delegate from the URLSession like this:

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

I'm guessing that my implementation in version 5 is wrong because I stopped getting response callback

Please advise on how to manage the request challenge properly in version 5


Solution

  • It isn't necessary to override the SessionDelegate to use client certificates. Alamofire will automatically use an attached URLCredential for client certificate challenges. Just attach the credential to the request:

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

    Also, your server trust check will return any trust as valid, which could be a security issue. I'd stop using that code immediately.