首先需要设置WKNavigationDelegate代理实现方法:
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler
此方法当web视图需要响应身份验证挑战时进行调用,
其中NSURLSessionAuthChallengeDisposition四个类型如下:
NSURLSessionAuthChallengeUseCredential = 0, /* 使用指定的凭据,可能为零 */
NSURLSessionAuthChallengePerformDefaultHandling = 1, /* 挑战的默认处理-如果未执行此委托,则忽略凭据参数.。 */
NSURLSessionAuthChallengeCancelAuthenticationChallenge = 2, /* 整个请求将被取消,凭据参数将被忽略.。*/
NSURLSessionAuthChallengeRejectProtectionSpace = 3, /* 此挑战被拒绝,并应尝试下一个身份验证保护空间,凭据参数被忽略。*/
}
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
弹窗版
NSString *hostName = webView.URL.host;
NSString *authenticationMethod = [[challenge protectionSpace] authenticationMethod];
if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
SecTrustRef secTrustRef = challenge.protectionSpace.serverTrust;
if (secTrustRef != NULL) {
SecTrustResultType result;
OSErr er = SecTrustEvaluate(secTrustRef, &result);
if (er != noErr) {
completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
return;
}
if (result == kSecTrustResultRecoverableTrustFailure) {
//证书不受信任
CFArrayRef secTrustProperties = SecTrustCopyProperties(secTrustRef);
NSArray *arr = CFBridgingRelease(secTrustProperties);
NSMutableString *errorStr = [NSMutableString string];
for (int i=0;i<arr.count;i++){
NSDictionary *dic = [arr objectAtIndex:i];
if (i != 0 ) [errorStr appendString:@" "];
[errorStr appendString:(NSString*)dic[@"value"]];
}
SecCertificateRef certRef = SecTrustGetCertificateAtIndex(secTrustRef, 0);
CFStringRef cfCertSummaryRef = SecCertificateCopySubjectSummary(certRef);
NSString *certSummary = (NSString *)CFBridgingRelease(cfCertSummaryRef);
NSString *title = @"该服务器无法验证";
NSString *message = [NSString stringWithFormat:@" 是否通过来自%@标识为 %@证书为%@的验证. \n%@" , @"我的app",hostName,certSummary, errorStr];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);}
]
];
[alertController addAction:[UIAlertAction actionWithTitle:@"Continue" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
NSURLCredential* credential = [NSURLCredential credentialForTrust:secTrustRef];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
}]];
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:alertController animated:YES completion:^{}];
});
return;
}
NSURLCredential* credential = [NSURLCredential credentialForTrust:secTrustRef];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
return;
}
completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
}
else {
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
}
无窗版
NSString *authenticationMethod = [[challenge protectionSpace] authenticationMethod];
if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSURLCredential *credential = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
}
网友评论