web-dev-qa-db-fra.com

Serveur NSURLSession + avec certificat auto-signé

J'ai une application qui est en production avec un serveur de développement qui a un certificat auto-signé.

J'essaie de tester NSURLSession et le téléchargement en arrière-plan, mais je n'arrive pas à dépasser - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler

Lorsque j'utilise NSURLConnection je peux le contourner en utilisant:

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {

    NSLog(@"canAuthenticateAgainstProtectionSpace %@", [protectionSpace authenticationMethod]);

    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {

    NSLog(@"didReceiveAuthenticationChallenge %@ %zd", [[challenge protectionSpace] authenticationMethod], (ssize_t) [challenge previousFailureCount]);

    [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}

Mais je ne sais pas comment faire fonctionner cela avec NSURLSession> :(

Voici ce que j'ai actuellement (cela ne fonctionne pas):

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
    NSLog(@"NSURLSession did receive challenge.");

    completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
}

J'ai également essayé de créer une catégorie de NSURLSession qui autoriserait n'importe quel certificat pour un hôte:

#import "NSURLRequest+IgnoreSSL.h"

@implementation NSURLRequest (IgnoreSSL)

+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)Host {
    return YES;
}

+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)Host {}

@end

Ce qui ne semble pas non plus aider.


MODIFIER

J'ai mis à jour cette méthode pour retourner:

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {

    //Creates credentials for logged in user (username/pass)
    NSURLCredential *cred = [[AuthController sharedController] userCredentials];

    completionHandler(NSURLSessionAuthChallengeUseCredential, cred);

}

Ce qui ne fait toujours rien.

30
random

Pour moi, votre premier exemple fonctionne bien. J'ai testé avec le code suivant sans problème (il est bien sûr très peu sûr car il autorise tout certificat de serveur).

@implementation SessionTest

- (void) startSession
{
    NSURL *url = [NSURL URLWithString:@"https://self-signed.server.url"];

    NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue]];

    NSURLSessionDataTask * dataTask = [defaultSession dataTaskWithURL:url
                                                completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                    if(error == nil)
                                                    {
                                                        NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
                                                        NSLog(@"Data: %@",text);
                                                    }
                                                    else
                                                    {
                                                        NSLog(@"Error: %@", error);
                                                    }
                                                }];

    [dataTask resume];
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
    completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
}

@end

Mise à jour: il s'agit de l'interface de classe, la classe SessionTest est NSURLSessionDataDelegate, pour démarrer le téléchargement de données, vous créez un objet SessionTest et appelez la méthode startSession.

@interface SessionTest : NSObject <NSURLSessionDelegate>

- (void) startSession;

@end
39
osanoj

Il n'y a pas suffisamment d'informations pour suggérer une solution concrète à votre problème.

Voici quelques exigences principales:

  • Puisque vous voulez une tâche en arrière-plan, assurez-vous d'avoir créé un objet NSSession approprié via backgroundSessionConfiguration:. L'utilisation de cette méthode de fabrique de classe est obligatoire pour obtenir sessions d'arrière-plan.

  • Pour les demandes exécutées en arrière-plan dans un processus distinct, seules les tâches upload et download sont prises en charge. Notez que, dans votre code d'origine, vous utilisez une tâche data.

  • Assurez-vous d'avoir correctement implémenté la méthode déléguée application:handleEventsForBackgroundURLSession:completionHandler: dans votre délégué d'application. Lorsque votre application n'est pas en cours d'exécution et lorsque la session s'exécute selon son propre processus et nécessite des informations d'identification, iOS redémarrera votre application en arrière-plan et la session d'arrière-plan appellera cette méthode déléguée. Voir aussi https://developer.Apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/Reference/Reference.html#//Apple_ref/occ/intfm/UIApplicationDelegate/application:handleEventsForBackgroundUR :

La désactivation de l'évaluation de l'approbation du serveur devrait fonctionner comme vous l'avez essayé dans votre premier exemple. Utilisez ceci uniquement pour le développement!

Voir aussi ( https://developer.Apple.com/library/ios/documentation/cocoa/Conceptual/URLLoadingSystem/Articles/UsingNSURLSession.html#//Apple_ref/doc/uid/TP40013509-SW44 )

1
CouchDeveloper