AFHTTPRequestOperation con authentication SSL y HTTP Basic Auth (error -1012)

Estoy intentando upload fotos a mi server web a través de AFHTTPRequestOperation . Aquí está mi AFHTTPSessionManager . Todas las requestes http a través de este manager funcionan perfectamente.

 - (AFHTTPSessionManager *)manager { if (_manager == nil) { _manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:@"https://my.domain.com/api/v2"]]; [_manager.requestSerializer setAuthorizationHeaderFieldWithUsername:@"username" password:@"password"]; AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; policy.allowInvalidCertificates = YES; _manager.securityPolicy = policy; } return _manager; } 

Pero cuando bash upload fotos con el event handlingl progreso:

 - (void)photoSend:(UIImage *)photo toUsers:(NSArray *)users completion:(CompletionHandler)completion progress:(ProgressionHandler)progress { NSDictionary *params = @{ @"token":self.token, @"to_usernames":[users componentsJoinedByString:@","], }; NSString *urlString = [[NSURL URLWithString:@"photo/send" relativeToURL:self.manager.baseURL] absoluteString]; NSMutableURLRequest *request = [self.manager.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:urlString parameters:params constructingBodyWithBlock:^(id <AFMultipartFormData> formData) { [formData appendPartWithFileData:UIImageJPEGRepresentation(photo,0.8) name:@"photo" fileName:@"image.jpg" mimeType:@"image/jpg"]; } error:nil]; AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; operation.responseSerializer = [AFJSONResponseSerializer serializer]; // Following 2 lines does not make sense. Http headers contains auth data without this code //NSURLCnetworkingential *cnetworkingential = [NSURLCnetworkingential cnetworkingentialWithUser:@"login" password:@"password" persistence:NSURLCnetworkingentialPersistenceNone]; //[operation setCnetworkingential:cnetworkingential]; [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { progress(totalBytesWritten*1.0/totalBytesExpectedToWrite); }]; [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { completion(operation.response, responseObject, operation.error); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { completion(operation.response, nil, error); }]; [self.manager.operationQueue addOperation:operation]; } 

Obtengo el siguiente error:

Error Domain = NSURLErrorDomain Code = -1012 "La operación no se pudo completar (NSURLErrorDomain error -1012.)" UserInfo = 0x994ff20 {NSErrorFailingURLKey = https://my.domain.com/v2/photo/send , NSErrorFailingURLStringKey = https : // mi.dominio.com/v2/photo/send }

Aquí está la solución:

 AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; policy.allowInvalidCertificates = YES; operation.securityPolicy = policy; 

Por lo tanto, los datos de authentication básicos de HTTP se proporcionan a la operación del administrador, pero la política de SSL no.

En AFNetworking puede usar AFSSLPinningMode para realizar cambios en las políticas de security, de modo que si su server no tiene SSL instalado, use el código siguiente

 let operation = AFHTTPRequestOperation(request: YourMutableRequestObject) let policy = AFSecurityPolicy(pinningMode: AFSSLPinningMode.None) policy.validatesDomainName = false policy.allowInvalidCertificates = true operation.securityPolicy = policy 

Y si su server utiliza un certificate, puede usar el código siguiente

 let operation = AFHTTPRequestOperation(request: YourMutableRequestObject) let policy = AFSecurityPolicy(pinningMode: AFSSLPinningMode.Certificate) policy.validatesDomainName = false policy.allowInvalidCertificates = true operation.securityPolicy = policy 

Antes de usar el código anterior, asegúrese de haber agregado el certificate cer en su package de aplicaciones, porque si no lo hace no podrá hacer las llamadas, puede get el file CER de su desarrollador web o de cualquier autoridad que le brinde el cer.

En caso de que si recibe un file crt del desarrollador web, debe convertirlo a cer mediante OpenSSL utilizando el código siguiente

 openssl x509 -in apache.crt -out yourCertFileName.cer -outform der 

Eso debería ser suficiente para hacer las llamadas

Actualizar

Según el nuevo patrón ATS de Apple en iOS 9, debes proporcionar algunos permissions dentro de tu file info.plist .

si quiere hacer una llamada insegura, dar a continuación es el XML que necesita para integrar dentro de info.plist (tenga en count que no va a get ningún relleno automático aquí, tiene que ver su plist como fuente y copyr + pegar el siguiente)

 <key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>yourserver.com</key> <dict> <!--Include to allow subdomains--> <key>NSIncludesSubdomains</key> <true/> <!--Include to allow HTTP requests--> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> <!--Include to specify minimum TLS version--> <key>NSTemporaryExceptionMinimumTLSVersion</key> <string>TLSv1.1</string> </dict> </dict> </dict> 

Apple también proporciona una forma de deshabilitar ATS que figura a continuación, es el XML para el mismo, pero no es recomendable

 <key>NSAppTransportSecurity</key> <dict> <!--Include to allow all connections --> <key>NSAllowsArbitraryLoads</key> <true/> </dict> 

En mi caso, ya que mi server estaba usando un certificate autofirmado, acabo de cambiar el AFSSLPinningMode a Certificate y funcionó como esperaba.

Espero que esto ayude a alguien