问题
情况1:公司业务需要私有化部署,对方服务器证书不受信导致网络无法请求成功,需要进行授信处理,报错结果如下:
An SSL error has occurred and a secure connection to the server cannot be made.
发生SSL错误和与服务器的安全连接无法进行。
情况2:因为公司域名出现问题,导致部分网址打不开,查看相关错误显示是因为服务器证书不受信,报错结果如下:
The certificate for this server is invalid. You might be connecting to a server that is pretending to be “xxx.xxx.com” which could put your confidential information at risk.
这个服务器的证书是无效的。你可能会连接到一个服务器,它是伪装“xxx.xxx.com”,可以把您的机密信息处于危险之中。
客户端信任证书的过程:
-
当客户端要访问服务器的时候,服务器向客户端发送受保护的信任证书
-
客户端判断是否对客户端发送的证书进行信任
-
如果信任.则客户端会安装公钥在客户端,而服务器就拥有受保护证书的密钥,每一次向服务器请求数据的时候,服务器会先将要发送的数据进行密钥加密,客户端对所传数据通过公钥解密
解决办法
- 让服务器更换服务器上的证书。(这种方案是最为合理的)
- 需要我们自己来创建一个证书让它受信,步骤如下:
-
在
Info.plist
文件中设置中Allow Arbitrary Loads in Web Content
设置为YES
,如果已经设置了NSAllowsArbitraryLoads
为YES
,可以不用设置。<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> <key>NSAllowsArbitraryLoadsInWebContent</key> <true/> </dict>
-


2. 在
WKNavigationDelegate
代理方法中实现自创证书并让其受信任
Swift
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
// 判断是否是信任服务器证书
if challenge.protectionSpace.authenticationMethod
== NSURLAuthenticationMethodServerTrust {
// 告诉服务器,客户端信任证书
// 创建凭据对象
let card = URLCredential.init(trust: challenge.protectionSpace.serverTrust!)
// 告诉服务器信任证书
completionHandler(URLSession.AuthChallengeDisposition.useCredential, card)
}
}
OC
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,card);
}
}
附:
如果是网络请求需要在NSURLSessionDataDelegate
代理方法中实现自创证书并让其受信任
//MARK: NSURLSessionDataDelegate
//只要请求的地址是HTTPS的, 就会调用这个代理方法
//challenge:质询
//NSURLAuthenticationMethodServerTrust:服务器信任
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{
NSLog(@"%@",challenge.protectionSpace);
if (![challenge.protectionSpace.authenticationMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"]) return;
/*
NSURLSessionAuthChallengeUseCredential 使用证书
NSURLSessionAuthChallengePerformDefaultHandling 忽略证书 默认的做法
NSURLSessionAuthChallengeCancelAuthenticationChallenge 取消请求,忽略证书
NSURLSessionAuthChallengeRejectProtectionSpace 拒绝,忽略证书
*/
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
}
参考资料:
关于 iOS 10 中 ATS 的问题
网友评论