【问题标题】:AFNetworking 3.0 and SSL authentication with setSessionDidReceiveAuthenticationChallengeBlockAFNetworking 3.0 和使用 setSessionDidReceiveAuthenticationChallengeBlock 的 SSL 身份验证
【发布时间】:2016-06-27 00:05:38
【问题描述】:

我正在尝试从 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 credential))块

【问题讨论】:

    标签: ios ssl afnetworking-3


    【解决方案1】:

    我正在解决同样的问题,在一些帮助下,我目前在 AFNetworking 上发现的只是这个问题。

    基本上在你的AFURLSessionManager中设置块- (void)setTaskDidReceiveAuthenticationChallengeBlock:([long block variable type here])block;

    证书以 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

    我现在正在尝试。

    【讨论】:

    • 您好,祝您好运。我也被困在同一个地方。
    猜你喜欢
    • 1970-01-01
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 2013-10-06
    相关资源
    最近更新 更多