我正在尝试从AFNetworking 2.0迁移到3.0.
在之前的版本中,我将使用setWillSendRequestForAuthenticationChallengeBlock创建AFHTTPRequestOperation并在另一个块中处理客户端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 :(可为空的NSURLSessionAuthChallengeDisposition(^)(NSURLSession * session,NSURLAuthenticationChallenge * challenge,NSURLCredential * _Nullable __autoreleasing * _Nullable credential))block
最佳答案 我正在研究同样的问题,我发现目前这个问题在AFNetworking上有一些帮助.
基本上设置块 – (void)setTaskDidReceiveAuthenticationChallengeBlock 🙁 [long block variable type here])block;在你的AFURLSessionManager中
证书以p12格式保存.
您需要在以下两行中更改证书的文件名和密码:
NSData *p12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cert" ofType:@"p12"]]; CFStringRef password = CFSTR("YOURPASSPHRASE");
设置此块的整个代码如下所示:
AFHTTPRequestSerializer *reqSerializer = [AFHTTPRequestSerializer serializer]; NSMutableURLRequest *request; 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 serializer]; [operation setSecurityPolicy:securityPolicy]; [operation setWillSendRequestForAuthenticationChallengeBlock:^(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge) { if ([challenge previousFailureCount] > 0) { //this will cause an authentication failure [[challenge sender] cancelAuthenticationChallenge:challenge]; NSLog(@"Bad Username Or Password"); 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); //if we want to ignore invalid server for certificates, we just accept the server if (kAllowsInvalidSSLCertificate) { [challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge: challenge]; return; } else if(result == kSecTrustResultProceed || result == kSecTrustResultUnspecified) { //When testing this against a trusted server I got kSecTrustResultUnspecified every time. But the other two match the description of a trusted server [challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge: challenge]; return; } } else if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) { //this handles authenticating the client certificate /* What we need to do here is get the certificate and an an identity so we can do this: NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:myCerts persistence:NSURLCredentialPersistencePermanent]; [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; It's easy to load the certificate using the code in -installCertificate It's more difficult to get the identity. We can get it from a .p12 file, but you need a passphrase: */ NSData *p12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cert" ofType:@"p12"]]; CFStringRef password = CFSTR("YOURPASSPHRASE"); const void *keys[] = { kSecImportExportPassphrase }; const void *values[] = { password }; CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL); CFArrayRef p12Items; OSStatus result = 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 certificates:(__bridge NSArray *)myCerts persistence:NSURLCredentialPersistencePermanent]; CFRelease(myCerts); [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; } else { [[challenge sender] cancelAuthenticationChallenge:challenge]; } } else if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodDefault || [[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodNTLM) { // For normal authentication based on username and password. This could be NTLM or Default. /* DAVCredentials *cred = _parentSession.credentials; NSURLCredential *credential = [NSURLCredential credentialWithUser:cred.username password:cred.password persistence:NSURLCredentialPersistenceForSession]; [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; */ NSLog(@"BASIC AUTHENTICATION"); } else { //If everything fails, we cancel the challenge. [[challenge sender] cancelAuthenticationChallenge:challenge]; } }]; [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"Success"); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Failure"); }]; [[NSOperationQueue mainQueue] addOperation:operation];
看到这个链接:https://github.com/AFNetworking/AFNetworking/issues/2316#issuecomment-115181437
我现在正在尝试这个.