Alamofire 4.9.1 sessionDidReceiveChallenge在iOS15不触发问题求助
问题成因
- iOS 15 对URLSession的认证挑战回调逻辑做了底层调整,针对网络请求的TLS认证场景,会优先触发带task参数的
urlSession(_:task:didReceive:completionHandler:)代理方法,不再走旧的无task参数的全局session级urlSession(_:didReceive:completionHandler:)回调。 - 你使用的Alamofire 4.9.1版本中,你赋值的
sessionDidReceiveChallenge闭包仅对应全局session级的无task参数代理回调,iOS 15下触发的task级代理方法对应独立的taskDidReceiveChallenge闭包,你没有对该闭包做赋值,因此自定义的认证逻辑完全不会执行,最终导致TLS认证失败。
解决方案
方案1:适配现有Alamofire 4.9.1版本(无需升级依赖)
额外对task级的认证挑战闭包赋值,复用你现有的认证逻辑即可,示例代码如下:
// 原有session级回调保留,兼容iOS 14及更低版本 dataProvider.sessionDelegate.sessionDidReceiveChallenge = { _, challenge in print("CHALLENGE ACCEPTED") if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate { return (.useCredential, cert.urlCredential()) } if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { guard let serverTrust = challenge.protectionSpace.serverTrust else { return (.performDefaultHandling, nil) } return (.useCredential, URLCredential(trust: serverTrust)) } return (.performDefaultHandling, nil) } // 新增task级回调赋值,兼容iOS 15及更高版本 dataProvider.sessionDelegate.taskDidReceiveChallenge = { _, _, challenge in print("CHALLENGE ACCEPTED (TASK LEVEL)") if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate { return (.useCredential, cert.urlCredential()) } if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { guard let serverTrust = challenge.protectionSpace.serverTrust else { return (.performDefaultHandling, nil) } return (.useCredential, URLCredential(trust: serverTrust)) } return (.performDefaultHandling, nil) }
注:上述代码把原有强制解包serverTrust的逻辑做了判空处理,避免极端场景下出现闪退
方案2:升级Alamofire到5.x版本
Alamofire 5.x版本已经统一适配了不同系统版本的认证挑战回调逻辑,你可以直接通过ServerTrustManager配置证书信任规则,或者使用统一的认证拦截逻辑,无需分别处理两个不同的代理回调。
内容的提问来源于stack exchange,提问作者Alecu Radu Truica
相关产品推荐
相关产品推荐

