2016-04-21 79 views
2

我試圖使用自簽名證書連接到API以進行測試。當didReceiveChallenge方法調用時,應用程序會凍結

-(NSData*)getDataFromPostRequestWithHeaders:(NSDictionary*)headers  withPostData:(NSData*)postData fromURL:(NSString*)urlString 
    { 
    __block NSData* responseData; 

    NSLog(@"URL is %@", urlString); 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString] 
                  cachePolicy:NSURLRequestUseProtocolCachePolicy 
                 timeoutInterval:10.0]; 
    [request setHTTPMethod:@"POST"]; 
    [request setHTTPBody:postData]; 
    [request setAllHTTPHeaderFields:headers]; 

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; 
    // [config setHTTPAdditionalHeaders:headers]; 
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil]; 
    NSLog(@"%@", @"NSURLSession started successfully"); 
    // I.e. no I do not need to have a queue of sessions running in parallel currently. 
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request 
               completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) 
              { 
               NSLog(@"%@", @"completionHandler called successfully"); 
                if (error) { 
                 NSLog(@"Error whilst executing post request: %@", error); 
                } else { 
                 NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response; 
                 NSLog(@"HTTP response from this request is %@", httpResponse); 
                 responseData = data; 
                } 
               }]; 
    [dataTask resume]; 

    return responseData; 
} 

這是我的didReceiveChallenge()方法:

-(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler 
{ 
    NSLog(@"%@", @"didReceiveChallenge method of NSURLSessionDelegate called successfully"); 
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) 
    { 
     if ([challenge.protectionSpace.host isEqualToString:@"https://dongu.ravenlabs.co.uk"]) 
     { 
      NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; 
      completionHandler(NSURLSessionAuthChallengeUseCredential, credential); // I.e. if it is this domain, then yes we can trust it. 
     } 
    } 
} 

第一個是一個登錄方法中調用像這樣:

-(NSString*)loginUserAndRetrieveSessionID:(NSString*)userName withPassword:(NSString*)password 
{ 
    __block NSDictionary *responseDict; 
    NSDictionary *loginHeaders = @{ @"content-type": @"application/json", 
           @"accept": @"application/json", 
           @"cache-control": @"no-cache", 
           }; 
    NSDictionary *parameters = @{ @"login": userName, 
            @"password": password }; 

    NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil]; 
    NSString *urlString = [DONGU_API_BASE_URL stringByAppendingString:@"/session/"]; 
    NSData *responseData = [self getDataFromPostRequestWithHeaders:loginHeaders withPostData:postData fromURL:urlString]; 
    if (responseData) 
    { 
    responseDict = [self getDictionaryFromResponseData:responseData]; 
    } 
    NSLog(@"%@", @"End of login method reached."); 
    return [responseDict objectForKey:@"session-token"]; 

} 

每當didReceiveChallenge被調用時,該應用完全凍結。有沒有解決的辦法?我試過使用GCD來調用登錄方法,並沒有喜悅。有沒有辦法解決?

回答

0

每次調用該方法時,都必須調用提供的完成處理程序,否則連接將不再進行。如果您不知道如何處理特定挑戰,請撥打電話...PerformDefaultHandling

此外,請注意,您禁用證書驗證的方式非常非常不安全。至少,您應該將提供的公鑰與存儲在應用程序中的已知有效公鑰一起進行比較,並且只有當您告訴操作系統使用該憑證時,該公鑰才與之匹配。否則,您將冒此代碼的風險,意外終止在您的發貨應用程序中,並失去TLS的所有好處。