如何使用AFNetworking 2进行摘要认证

5

我已经搜索了一段时间关于“使用摘要认证的AFNetworking 2”的讨论,但是没有找到有用的讨论(除了这个,但不幸的是它似乎是针对AFNetworking 1的)。

这是我的未进行身份验证的代码:

NSString* apiURL = @"https://api.example.com/WS.asmx";
AFHTTPSessionManager* manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager
    GET:apiURL 
    parameters: [NSDictionary dictionaryWithObjectsAndKeys:@"ID", 1234 , nil]
    success:^(NSURLSessionDataTask *task, id responseObject) {
        NSLog(@"JSON: %@", responseObject);
    }
    failure:^(NSURLSessionDataTask *task, NSError *error) {
        NSLog(@"WS request failed: %@", error);
    }
];

什么情况下Digest Auth代码会起作用,以及它如何起作用?

4个回答

2
我最近升级到AFNetworking-3,不再支持NSURLConnection。
当我改为NSURLSession时,遇到了同样的问题。
谢谢Bob,修改AFNetworkings中的AFURLSessionManager.m对我很有帮助。
但是在那之后,我发现如果设置了self.taskDidReceiveAuthenticationChallenge,我们就不必更改AFNetworkings代码,这是一个更简单的方法。
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

NSURLCredential *myCredential = [[NSURLCredential alloc] initWithUser:@"username" password:@"password" persistence:NSURLCredentialPersistenceForSession];

[manager setTaskDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession * _Nonnull session, NSURLSessionTask * _Nonnull task, NSURLAuthenticationChallenge * _Nonnull challenge, NSURLCredential *__autoreleasing  _Nullable * _Nullable credential) {
    if (challenge.previousFailureCount == 0) {
        *credential = myCredential;
        return NSURLSessionAuthChallengeUseCredential;
    } else {
        return NSURLSessionAuthChallengePerformDefaultHandling;
    }
}];

2
这个问题有点老,但我必须做到这一点,而且我找不到任何内置的方法来处理它。 我使用的解决方案是编辑AFNetworking的AFURLSessionManager.m。 基本上,您修改此委托方法以支持HTTP摘要,这里是一个完整的示例。
    - (void)URLSession:(NSURLSession *)session
                  task:(NSURLSessionTask *)task
    didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
     completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
    {
        NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
        __block NSURLCredential *credential = nil;

        if (self.taskDidReceiveAuthenticationChallenge) {
            disposition = self.taskDidReceiveAuthenticationChallenge(session, task, challenge, &credential);
        } else {
            if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
                if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
                    disposition = NSURLSessionAuthChallengeUseCredential;
                    credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
                } else {
                    disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
                }
            } else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPDigest]) {
                NSDictionary *userkeys = [[NSURLCredentialStorage sharedCredentialStorage] credentialsForProtectionSpace:challenge.protectionSpace];

                credential = [userkeys objectForKey:(NSString *)[[userkeys allKeys] objectAtIndex: 0]];
                if (credential) {
                    disposition = NSURLSessionAuthChallengeUseCredential;
                } else {
                    disposition = NSURLSessionAuthChallengePerformDefaultHandling;
                }
            }else {
                disposition = NSURLSessionAuthChallengePerformDefaultHandling;
            }
        }

        if (completionHandler) {
            completionHandler(disposition, credential);
        }
    }

在进行此项挑战之前,您需要向sharedCredentialStorage添加凭据。您可以查看苹果文档,因为这相当简单,但请确保保护空间完全匹配,包括领域。

希望对某人有所帮助。


0
花了我一些时间才想出来,而且我没有看到任何适用于AFNetworking 4.0的解决方案(需要4.0,因为它移除了已弃用的UIWebView,如果被发现,苹果现在会拒绝),做这个:;
NSURLCredential *myCredential = [[NSURLCredential alloc] initWithUser:username password:password persistence:NSURLCredentialPersistenceForSession];

[manager setAuthenticationChallengeHandler:^id _Nonnull(NSURLSession * _Nonnull session, NSURLSessionTask * _Nonnull task, NSURLAuthenticationChallenge * _Nonnull challenge, void (^ _Nonnull completionHandler)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable credential)) {
    if (challenge.previousFailureCount == 0) {
        return myCredential;
    } else {
        return @(NSURLSessionAuthChallengePerformDefaultHandling);
    }
}];

-1

我刚刚使用了以下代码,运行得很好

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:@"Username" password:@"Password" persistence:NSURLCredentialPersistenceForSession];
[manager setCredential:credential]; 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接