我正在尝试从AFNetworking 2.0迁移到3.0。
在以前的版本中,我将创建一个AFHTTPRequestOperation并使用setWillSendRequestForAuthenticationChallengeBlock在另一个块中处理客户端SSL身份验证。
例如:
[operation setWillSendRequestForAuthenticationChallengeBlock:^(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge) {
if ([challenge previousFailureCount] > 0) {
//this will cause an authentication failure
[[challenge sender] cancelAuthenticationChallenge:challenge];
return;
}
//this is checking the server certificate
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
SecTrustResultType result;
//This takes the serverTrust object and checkes it against your keychain
SecTrustEvaluate(challenge.protectionSpace.serverTrust, &result);
有人可以给我看一个如何使用AFHTTPSessionManager做到这一点的例子吗?
我是否需要使用AFURLSessionManager发出请求?我确实在这里看到了一个块方法:
(void)setSessionDidReceiveAuthenticationChallengeBlock:(nullable NSURLSessionAuthChallengeDisposition(^)(NSURLSession * session,NSURLAuthenticationChallenge * challenge,NSURLCredential * _Nullable __autoreleasing * _Nullable凭证))
最佳答案
我正在处理相同的问题,目前发现的所有问题都在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] parameters:nil error:nil];
AFSecurityPolicy * securityPolicy = [[AFSecurityPolicy alloc] init];
[securityPolicy setAllowInvalidCertificates:kAllowsInvalidSSLCertificate];
AFHTTPRequestOperation * operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFHTTPResponseSerializer序列化器];
[操作setSecurityPolicy:securityPolicy];
[操作setWillSendRequestForAuthenticationChallengeBlock:^(NSURLConnection * connection,NSURLAuthenticationChallenge * challenge){
如果([challenge previousFailureCount]> 0){
//这将导致身份验证失败
[[挑战发件人] cancelAuthenticationChallenge:challenge];
NSLog(@“错误的用户名或密码”);
返回;
}
//这正在检查服务器证书
如果([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){
SecTrustResultType结果;
//这将使用serverTrust对象并根据您的钥匙串(keychain)对其进行检查
SecTrustEvaluate(challenge.protectionSpace.serverTrust,&result);
//如果我们想忽略无效的服务器获取证书,我们只接受该服务器
如果(kAllowsInvalidSSLCertificate){
[challenge.sender useCredential:[NSURLCredential credentialForTrust:Challenge.protectionSpace.serverTrust] forAuthenticationChallenge:Challenge];
返回;
} else if(结果== kSecTrustResultProceed ||结果== kSecTrustResultUnspecified){
//在针对可信任的服务器进行测试时,每次都会得到kSecTrustResultUnspecified。但是其他两个与受信任服务器的描述匹配
[challenge.sender useCredential:[NSURLCredential credentialForTrust:Challenge.protectionSpace.serverTrust] forAuthenticationChallenge:Challenge];
返回;
}
}否则,如果([[[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate){
//这将处理对客户端证书的身份验证
/*
我们在这里需要做的是获取证书和身份,以便我们可以这样做:
NSURLCredential * credential = [NSURLCredential credentialWithIdentity:identity certificate:myCerts persistence: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);
if(result == 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持久性:NSURLCredentialPersistencePermanent];
CFRelease(myCerts);
[[挑战发件人] useCredential:credential forAuthenticationChallenge:challenge];
} 别的 {
[[挑战发件人] cancelAuthenticationChallenge:challenge];
}
}否则,如果([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodDefault || [[[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodNTLM){
//用于基于用户名和密码的普通身份验证。这可能是NTLM或默认值。
/*
DAVCredentials * cred = _parentSession.credentials;
NSURLCredential * credential = [NSURLCredential credentialWithUser:cred.username密码:cred.password持久性:NSURLCredentialPersistenceForSession];
[[挑战发件人] useCredential:credential forAuthenticationChallenge:challenge];
*/
NSLog(@“基本认证”);
} 别的 {
//如果一切都失败了,我们取消挑战。
[[挑战发件人] cancelAuthenticationChallenge:challenge];
}
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation * operation,id responseObject){
NSLog(@“成功”);
} failure:^(AFHTTPRequestOperation * operation,NSError * error){
NSLog(@“失败”);
}];
[[NSOperationQueue mainQueue] addOperation:operation];
看到这个链接:https://github.com/AFNetworking/AFNetworking/issues/2316#issuecomment-115181437
我正在尝试这个。
关于ios - 使用setSessionDidReceiveAuthenticationChallengeBlock进行AFNetworking 3.0和SSL身份验证,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35945398/