5

我一直在尋找「AFNetworking 2與摘要式身份驗證」一段時間,並沒有找到有用的討論(除了this one,但不幸的是它看起來像它的AFNetworking 1) 。如何使用AFNetworking 2與摘要式身份驗證

這裏是我的代碼,而無需身份驗證:

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); 
    } 
]; 

在哪裏以及如何能消化驗證碼踢?

回答

2

這個問題有點老,但我不得不這樣做,我找不到任何處理它的方法。 我使用的解決方案是編輯AFNetworkings 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

真的很好的解決方案。 –

-1

我只是用下面的代碼,並能正常工作

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

這工作正常直到AFNetwork版本3。 –

2

我最近升級到AFNetworking-3,有沒有NSURLConnection支持了。

當我更改爲NSURLSession時,我遇到了同樣的問題。

謝謝鮑勃,編輯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; 
    } 
}];