Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSURLSession + server with self signed cert

I have an app that is production along with a development server that has a self signed certificate.

I am attempting to test NSURLSession and background downloading but can't seem to get past - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler

When I use NSURLConnection I am able to bypass it using:

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

But I can't figure out how to get this to work with NSURLSession >:(

This is what I have currently (that doesn't work):

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

I also tried creating a category of NSURLSession that would allow any certificate for a host:

#import "NSURLRequest+IgnoreSSL.h"  @implementation NSURLRequest (IgnoreSSL)  + (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host {     return YES; }  + (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host {}  @end 

Which also doesn't seem to help.


EDIT

I've updated this method to return:

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

Which still does nothing.

like image 696
random Avatar asked Nov 26 '13 23:11

random


1 Answers

For me your first example is working fine. I have tested with the following code without problems (it is of course very insecure since it allows any server certificate).

@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 

Update: This is the class interface, the SessionTest class is the NSURLSessionDataDelegate, to start the data download you create a SessionTest object and call the startSession method.

@interface SessionTest : NSObject <NSURLSessionDelegate>  - (void) startSession;  @end 
like image 119
osanoj Avatar answered Sep 28 '22 04:09

osanoj