我正在尝试从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/

10-14 03:13