2013-02-15 16 views
8

Non riesco a richiedere il servizio Web utilizzando https. Ricevo questo tipo di errore:Richiesta di servizio Web su SSL

An error occured : The certificate for this server is invalid. You might be connecting to a server that is pretending to be “SERVER_ADDRESS” which could put your confidential information at risk. 

Non sto utilizzando NSUrlConnectionDelegate. Ecco il mio metodo:

- (void)sendRequestWithUrl:(NSURL*)url block:(void (^)(NSDictionary *dict, NSError *error)) block{ 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 
    [request setHTTPMethod:@"POST"]; 
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
    NSError* err = nil; 
    NSHTTPURLResponse* rsp = nil; 
    // Perform the request synchronously on this thread 
    NSData *rspData = [NSURLConnection sendSynchronousRequest:request returningResponse:&rsp error:&err]; 
    if (rspData && err == nil) { 
     NSDictionary *result = [NSJSONSerialization JSONObjectWithData:rspData options:NSJSONReadingMutableLeaves error:&err]; 
     if(result) { 
      block(result, err); 
     } else { 
      block(nil, err); 
     } 
    }else{ 
     DLog(@"Requesting URL: %@ An error occured : %@",url,[err localizedDescription]); 
     block(nil, err); 
    } 
} 

Come posso risolvere questo problema?

+1

Mi sembra che tu abbia problemi con un certificato autofirmato .. corretto? Vi consiglio di passare a una lib come [AFNetworking] (https://github.com/AFNetworking/AFNetworking/blob/master/README.md) o [MKNetworking] (https://github.com/MugunthKumar/MKNetworkKit /blob/master/README.mdown), che rende questo tipo di problemi più facile da gestire. Controllare: http://stackoverflow.com/questions/13077753/need-to-view-website-with-a-self-signed-certificate-and-http-authentication –

+1

Inoltre, possibile duplicato di: http: // stackoverflow. it/questions/933331/how-to-use-nsurlconnection-to-connect-with-ssl-for-an-untrusted-cert –

+1

Non voglio usare altre librerie. Anche in altre domande la soluzione è deprivata – Streetboy

risposta

1

Si dovrebbe aggiungere sotto i metodi delegato alla classe di comunicazione.

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{ 
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) 
    { 
     if ([YOUR_HOST isEqualToString:challenge.protectionSpace.host]) 
     { 
      [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];   
     } 
    } 
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; 
} 

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace 
{ 
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]; 
} 
0

questo avvenga sempre per il certificato auto-firmato. Utilizzando NSURLConnectionDelegate

- (BOOL)connection:(NSURLConnection *)connection 
canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace 
{ 
    if ([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { 
     return YES; 
    } 
} 
+0

Come si può regolare questo codice per il mio?So come farlo con NSURLConnectionDelegate, ma come farlo utilizzando i blocchi – Streetboy

+0

perché non si desidera utilizzare NSURLConnectionDelegate? C'è qualcosa per infrangere il tuo codice? –

+0

Vorrei aggiornare il mio codice corrente, perché in un altro modo avrei bisogno di fare molte modifiche poiché ora tutto è fatto in blocchi. Mi piace anche scrivere codice in questo approccio – Streetboy

0

Provare questo metodo delegato ha risolto lo stesso problema per me.

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { 
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 
    [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; 
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; 
} 
2

Ebbene la mia soluzione era quello di creare classe AsyncURLConnection questo codice ho trovato da qualche parte http://stackoverflow.com, ma non riesce a trovare ora. Quindi darò il codice:

AsyncURLConnection:

.h

#import <Foundation/Foundation.h> 

typedef void (^completeBlock_t)(NSData *data); 
typedef void (^errorBlock_t)(NSError *error); 

@interface AsyncURLConnection : NSObject{ 
    NSMutableData *data_; 
    completeBlock_t completeBlock_; 
    errorBlock_t errorBlock_; 
} 

+ (id)request:(NSString *)requestUrl completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock; 
- (id)initWithRequest:(NSString *)requestUrl completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock; 
+ (id)requestWithMutable:(NSMutableURLRequest *)request completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock; 
- (id)initWithMutableRequest:(NSMutableURLRequest *)request completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock; 
@end 

.m

#import "AsyncURLConnection.h" 

@implementation AsyncURLConnection 

+ (id)requestWithMutable:(NSMutableURLRequest *)request completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock 
{ 
    return [[self alloc] initWithMutableRequest:request completeBlock:completeBlock errorBlock:errorBlock]; 
} 

+ (id)request:(NSString*)requestUrl completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock 
{ 
    return [[self alloc] initWithRequest:requestUrl 
          completeBlock:completeBlock errorBlock:errorBlock]; 
} 

- (id)initWithRequest:(NSString *)requestUrl completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock 
{ 
    if ((self=[super init])) { 
     data_ = [[NSMutableData alloc] init]; 
     completeBlock_ = [completeBlock copy]; 
     errorBlock_ = [errorBlock copy]; 
     NSURL *url = [NSURL URLWithString:requestUrl]; 
     NSURLRequest *request = [NSURLRequest requestWithURL:url]; 
     [NSURLConnection connectionWithRequest:request delegate:self]; 
    } 
    return self; 
} 

- (id)initWithMutableRequest:(NSMutableURLRequest *)request completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock 
{ 
    if ((self=[super init])) { 
     data_ = [[NSMutableData alloc] init]; 
     completeBlock_ = [completeBlock copy]; 
     errorBlock_ = [errorBlock copy]; 
     [NSURLConnection connectionWithRequest:request delegate:self]; 
    } 
    return self; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    [data_ setLength:0]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    [data_ appendData:data]; 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    completeBlock_(data_); 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{ 
    errorBlock_(error); 
} 


- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 
    if ([challenge previousFailureCount] == 0) 
    { 
     NSURLCredential *newCredential; 
     newCredential=[NSURLCredential credentialWithUser:@"someUser" 
               password:@"someUser" 
               persistence:NSURLCredentialPersistenceForSession]; 
     [[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge]; 
     DLog(@"responded to authentication challenge"); 

    }else{ 
     DLog(@"previous authentication failure"); 
    } 
} 

Quindi, in alcuni controller di questa classe potrebbe essere utilizzato:

+ (void) downloadFileForURL:(NSURL *) url completionBlock:(void (^)(NSData *data, NSError *error)) block { 
    NSString *requestURL = @"https://www.google.lt/restServer/Method"; 
    [AsyncURLConnection request:requestURL completeBlock:^(NSData *data) { 
     /* success! */ 
     dispatch_queue_t downloadQueue = dispatch_queue_create("Download queue", NULL); 
     dispatch_async(downloadQueue, ^{ 
      /* process downloaded data in Concurrent Queue */ 
      if (data != nil) { 
       block(data, nil); 
      }else{ 
       block(nil,nil); 
      } 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       /* update UI on Main Thread */ 
      }); 
     }); 
    } errorBlock:^(NSError *error) { 
     /* error! */ 
     block(nil,error); 
    }]; 
} 

Spero che questo codice possa essere d'aiuto.

Grazie a tutti per le risposte.

Problemi correlati