2016-04-21 78 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的所有好处。