Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I allow https connection using AFNetworking?

I have AFNetworking set up but it is not accept https urls. How can I get AFNEtworking to connect via ssl.

I have the following code:

  NSMutableURLRequest *apiRequest =
[self multipartFormRequestWithMethod:@"POST"
                                path: pathstr
                          parameters: params
           constructingBodyWithBlock: ^(id <AFMultipartFormData>formData)
           {
               //TODO: attach file if needed
           }];



AFJSONRequestOperation* operation = [[AFJSONRequestOperation alloc] initWithRequest: apiRequest];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    //success!
    completionBlock(responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    //failure :(

    NSLog(@"%@", error);
    completionBlock([NSDictionary dictionaryWithObject:[error localizedDescription] forKey:@"error"]);
}];

[operation start];
like image 409
Chris Hansen Avatar asked Feb 15 '13 17:02

Chris Hansen


3 Answers

operation.securityPolicy.allowInvalidCertificates = YES;

This code is very important. If you dont add this you will get an error.

like image 178
Oliver Avatar answered Oct 02 '22 15:10

Oliver


This will obviously only work if you have a non self-signed cert OR you add:

#define _AFNETWORKING_ALLOW_INVALID_SSL_CERTIFICATES_ to your pch file. If you are using cocoa pods for this you will likely need to subclass AFHTTPRequestOperation and implement:

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    if ([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) {

        if ([self bypassSslCertValidation:protectionSpace])
            return YES;
        else
            return [super connection:connection canAuthenticateAgainstProtectionSpace:protectionSpace];

    }
    return [super connection:connection canAuthenticateAgainstProtectionSpace:protectionSpace];

}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        if ([self bypassSslCertValidation:challenge.protectionSpace]) {
            [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
            return;
        }
        else
            return [super connection:connection didReceiveAuthenticationChallenge:challenge];
        return;
    }
}

- (BOOL) bypassSslCertValidation:(NSURLProtectionSpace *) protectionSpace
{
    if (ENVIRONMENT_TYPE == DEV_ENV || ENVIRONMENT_TYPE == STAGING_ENV) {
        return YES;
    }
    return NO;
}

Then tell AFNEtworking to use the new subclass:

AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@""]];
[client registerHTTPOperationClass:[YourSubClassHTTPRequestOperation class]];

It's not the easiest thing to do in the world and technically ignoring self-signed isn't making it work, but if you use standard SLL certificates It's probable it will work just fine, remember to remove this code or make it only available when debugging if you plan to release.

Adding to answer because comments have char limits!

Few choices looking at the headers

Return operation that can be manually added to the queue:

- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest

Or pass in your custom subclass operation to this one:

- (void)enqueueHTTPRequestOperation:(AFHTTPRequestOperation *)operation;
like image 32
Holyprin Avatar answered Oct 02 '22 15:10

Holyprin


Try this code.

  NSMutableURLRequest *apiRequest =
[self multipartFormRequestWithMethod:@"POST"
                                path: pathstr
                          parameters: params
           constructingBodyWithBlock: ^(id <AFMultipartFormData>formData)
           {
               //TODO: attach file if needed
           }];



AFJSONRequestOperation* operation = [[AFJSONRequestOperation alloc] initWithRequest: apiRequest];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    //success!
    completionBlock(responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    //failure :(

    NSLog(@"%@", error);
    completionBlock([NSDictionary dictionaryWithObject:[error localizedDescription] forKey:@"error"]);
}];
operation.securityPolicy.allowInvalidCertificates = YES;
[operation start];
like image 29
Voda Ion Avatar answered Oct 02 '22 14:10

Voda Ion