我正在解决同样的问题,目前我发现的只是 AFNetworking 上的这个问题,需要一些帮助。
基本上- (void)setTaskDidReceiveAuthenticationChallengeBlock:([long block variable type here])block;
在你的AFURLSessionManager
证书以 p12 格式保存。您需要在这两行中更改证书的文件名和密码:
NSData *p12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cert" ofType:@"p12"]];
CFStringRef 密码 = CFSTR("YOURPASSPHRASE");
设置此块的整个代码如下所示:
AFHTTPRequestSerializer *reqSerializer = [AFHTTPRequestSerializer 序列化器];
NSMutableURLRequest *请求;
request = [reqSerializer requestWithMethod:method URLString:[actionURL absoluteString] 参数:nil error:nil];
AFSecurityPolicy *securityPolicy = [[AFSecurityPolicy alloc] init];
[securityPolicy setAllowInvalidCertificates:kAllowsInvalidSSLCertificate];
AFHTTPRequestOperation *操作 = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFHTTPResponseSerializer 序列化器];
[操作 setSecurityPolicy:securityPolicy];
[操作 setWillSendRequestForAuthenticationChallengeBlock:^(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge) {
if ([挑战 previousFailureCount] > 0) {
//这将导致认证失败
[[挑战发件人] cancelAuthenticationChallenge:challenge];
NSLog(@"错误的用户名或密码");
返回;
}
//这是检查服务器证书
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
SecTrustResultType 结果;
//这需要 serverTrust 对象并根据您的钥匙串检查它
SecTrustEvaluate(challenge.protectionSpace.serverTrust, &result);
//如果我们想忽略证书的无效服务器,我们只接受服务器
if (kAllowsInvalidSSLCertificate) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
返回;
} 否则如果(结果 == kSecTrustResultProceed || 结果 == kSecTrustResultUnspecified){
//当针对受信任的服务器进行测试时,我每次都得到 kSecTrustResultUnspecified。但其他两个匹配受信任服务器的描述
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
返回;
}
} else if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {
//这处理验证客户端证书
/*
我们需要在这里做的是获取证书和一个身份,以便我们可以这样做:
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:身份证书:myCerts 持久性:NSURLCredentialPersistencePermanent];
[[挑战发件人] useCredential:credential forAuthenticationChallenge:challenge];
使用 -installCertificate 中的代码很容易加载证书
更难获得身份。
我们可以从 .p12 文件中获取它,但您需要一个密码:
*/
NSData *p12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cert" ofType:@"p12"]];
CFStringRef 密码 = CFSTR("YOURPASSPHRASE");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { 密码 };
CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, 键, 值, 1, NULL, NULL);
CFArrayRef p12Items;
OSStatus 结果 = SecPKCS12Import((__bridge CFDataRef)p12Data, optionsDictionary, &p12Items);
如果(结果 == noErr){
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(p12Items, 0);
SecIdentityRef identityApp =(SecIdentityRef)CFDictionaryGetValue(identityDict,kSecImportItemIdentity);
SecCertificateRef certRef;
SecIdentityCopyCertificate(identityApp, &certRef);
SecCertificateRef certArray[1] = { certRef };
CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL);
CFRelease(certRef);
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identityApp 证书:(__bridge NSArray *)myCerts persistence:NSURLCredentialPersistencePermanent];
CFRelease(myCerts);
[[挑战发件人] useCredential:credential forAuthenticationChallenge:challenge];
} 别的 {
[[挑战发件人] cancelAuthenticationChallenge:challenge];
}
} else if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodDefault || [[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodNTLM) {
// 用于基于用户名和密码的正常身份验证。这可以是 NTLM 或默认值。
/*
DAVCredentials *cred = _parentSession.credentials;
NSURLCredential *credential = [NSURLCredential credentialWithUser:cred.username password:cred.password persistence:NSURLCredentialPersistenceForSession];
[[挑战发件人] useCredential:credential forAuthenticationChallenge:challenge];
*/
NSLog(@"基本认证");
} 别的 {
//如果一切都失败了,我们取消挑战。
[[挑战发件人] cancelAuthenticationChallenge:challenge];
}
}];
[操作 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"成功");
} 失败:^(AFHTTPRequestOperation *操作,NSError *错误){
NSLog(@"失败");
}];
[[NSOperationQueue mainQueue] addOperation:operation];
请参阅此链接:https ://github.com/AFNetworking/AFNetworking/issues/2316#issuecomment-115181437
我现在正在尝试这个。