Objective-C SSL Synchronous Connection

2019-02-18 10:57发布

问题:

I'm a little new to objective-C but have run across a problem that I can't solve, mostly because I'm not sure I am implementing the solution correctly.

I am trying to connect using a Synchronous Connection to a https site with a self-signed certificate. I am getting the

Error Domain=NSURLErrorDomain Code=-1202 "untrusted server certificate"

Error that I have seen some solutions to on this forum. The solution i found was to add:

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

}

to the NSURLDelegate to accept all certificates. When I connect to the site using just a:

NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://examplesite.com/"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];  
    NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; 

It works fine and I see the challenge being accepted. However when I try to connect using the synchronous connection I still get the error and I don't see the challenge functions being called when I put in logging.

How can I get the synchronous connection to use the challenge methods? Is it something to do with the delegate:self part of the URLConnection? I also have logging for sending/receiving data within the NSURLDelegate that is called by my connection function but not by the synchronous function.

What I am using for the synchronous part:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: [NSURL URLWithString:@"https://examplesite.com/"]];  
        [request setHTTPMethod: @"POST"];  
        [request setHTTPBody: [[NSString stringWithString:@"username=mike"] dataUsingEncoding: NSUTF8StringEncoding]];  
        dataReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];  
        NSLog(@"%@", error);  
        stringReply = [[NSString alloc] initWithData:dataReply encoding:NSUTF8StringEncoding];  
        NSLog(@"%@", stringReply);  
        [stringReply release];  
        NSLog(@"Done"); 

Like I mentioned I'm a little new to objective C so be kind :)

Thanks for any help. Mike

回答1:

According to the Apple docs (URL Loading System Programming Guide), the synchronous NSURLRequest method is not recommended because "because it has severe limitations". It would appear that the lack of the ability to control what certificates are acceptable is one of these limitations.

And yes, you are right, it is the delegate:self on the NSURLConnection setup that causes your delegate methods to be invoked. Because the simple (or simplistic) synchronous sendSynchronousRequest: call doesn't provide a way to specify a delegate, those delegate methods aren't used.