iOS网络模块实现URLSessionDelegate绕过证书验证失败求助
iOS框架绕过证书验证失败问题
问题详情
我做了一个作为网络模块的iOS框架,要绕过证书验证,但网上找的基于URLSessionDelegate的方案都没用。
当前代码
extension FCSession: URLSessionDelegate { func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { switch challenge.protectionSpace.authenticationMethod { case NSURLAuthenticationMethodServerTrust: if let serverTrust = challenge.protectionSpace.serverTrust { let credential = URLCredential(trust: serverTrust) completionHandler(.useCredential, credential) } default: completionHandler(.rejectProtectionSpace, nil) } } }
报错信息
Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
"<cert(0x10880ac00)
已尝试操作
直接把serverTrust传入completionHandler,还是报同样的错:
completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
解决办法
1. 确认URLSession绑定了正确的Delegate
不能用默认的URLSession.shared,必须手动初始化会话并指定delegate为FCSession实例:
let config = URLSessionConfiguration.default let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
如果会话没绑定Delegate,自定义的证书验证方法根本不会触发。
2. 显式标记服务器信任有效
只返回URLCredential可能不够,需要手动设置信任锚点:
extension FCSession: URLSessionDelegate { func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, let serverTrust = challenge.protectionSpace.serverTrust else { completionHandler(.performDefaultHandling, nil) return } // 允许信任任意证书 SecTrustSetAnchorCertificates(serverTrust, []) SecTrustSetAnchorCertificatesOnly(serverTrust, false) let credential = URLCredential(trust: serverTrust) completionHandler(.useCredential, credential) } }
3. 配置ATS例外
在项目的Info.plist里添加ATS配置,允许非安全连接:
<key>NSAppTransportSecurity</key> <dict> <!-- 全局允许(仅测试用,上线建议用特定域名例外) --> <key>NSAllowsArbitraryLoads</key> <true/> <!-- 特定域名例外(更安全) --> <!-- <key>NSExceptionDomains</key> <dict> <key>你的服务器域名.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict> --> </dict>
4. 验证Delegate方法是否触发
在证书验证方法里加个打印,确认方法是否被调用:
print("证书验证方法已触发")
如果没打印,说明会话的Delegate没设置对,或者请求用了其他会话实例。
内容的提问来源于stack exchange,提问作者Filipe Marques
相关产品推荐
相关产品推荐

