2016-04-21 9 views
2

aufgerufen wird. Ich versuche, eine Verbindung zu einer API herzustellen, indem ich ein selbstsigniertes Zertifikat zum Testen verwende.App friert ein, wenn die Methode 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; 
} 

Das ist mein didReceiveChallenge() Methode:

-(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"]; 

} 

Wenn didReceiveChallenge, die App aufgerufen wird, friert vollständig:

-(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. 
     } 
    } 
} 

Die erste in einem Login-Methode wie so genannt wird, . Gibt es einen Weg dahin? Ich habe versucht, GCD für den Aufruf der Login-Methode und keine Freude. Gibt es einen Weg dazu?

Antwort

0

Sie müssen den bereitgestellten Complete-Handler jedes Mal aufrufen, wenn diese Methode aufgerufen wird, da die Verbindung sonst keinen weiteren Fortschritt macht. Wenn Sie nicht wissen, was mit einer bestimmten Herausforderung zu tun ist, rufen Sie sie unter ...PerformDefaultHandling an.

Bitte beachten Sie außerdem, dass die Art und Weise, wie Sie die Zertifikatvalidierung deaktivieren, sehr, sehr unsicher ist. Als Mindestanforderung sollten Sie den bereitgestellten öffentlichen Schlüssel mit einem in Ihrer App gespeicherten öffentlichen Schlüssel vergleichen, der bekanntermaßen gültig ist, und nur dann, wenn es übereinstimmt, sollten Sie dem Betriebssystem mitteilen, dass es diesen Berechtigungsnachweis verwenden soll. Andernfalls besteht die Gefahr, dass dieser Code versehentlich in Ihre Versand-App gelangt und alle Vorteile von TLS verliert.