How to Use Nsurlconnection to Connect With Ssl For an Untrusted Cert

How to use NSURLConnection to connect with SSL for an untrusted cert?

There is a supported API for accomplishing this! Add something like this to your NSURLConnection delegate:

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

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

[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

Note that connection:didReceiveAuthenticationChallenge: can send its message to challenge.sender (much) later, after presenting a dialog box to the user if necessary, etc.

NSURLConnection, NSURLRequest, untrusted cert and user authentication

You can only reply to an NSURLAuthenticationChallenge with a credential for that challenge. You can determine what type of challenge you've received using:

[[challenge protectionSpace] authenticationMethod]

The possible values are documented here. In the case of an invalid server certificate, the authentication method will be NSURLAuthenticationMethodServerTrust. In your code, you should check the authentication method and respond appropriately.

if ([challenge previousFailureCount] > 0) {
// handle bad credentials here
[[challenge sender] cancelAuthenticationChallenge:challenge];
return;
}

if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodServerTrust) {
// check if the user has previously accepted the certificate, otherwise prompt
} else if ([[challenge protectionSpace] authenticationMethod] == /* your supported authentication method here */) {
[[challenge sender] useCredential:/* your user's credential */ forAuthenticationChallenge:challenge];
}

It's not an error if you don't get both authentication challenges each time. You can cache credentials when you create them. If you do, you won't necessarily be prompted again.

Loading HTTPS in UIWebView

Actually found a solution here: UIWebView to view self signed websites (No private api, not NSURLConnection) - is it possible?

What it actually does is to intercept the UIWebView to launch a NSURLConnection to allow the server to be authenticated, therefore then continue the connection using UIWebView, and cancels out the NSURLConnection. Reason so is because after authorising the server once, the rest of the continuous connection would not be blocked. Hope i'm clear. :)

How can I call a https endpoint by NSURLConnection sendSynchronousRequest in case of untrusted certificate?

You answered your question already yourself:

By using sendSynchronousRequest I can't bypass this problem, because to bypass it, I need to set delegate for NSURLConnection, but in case of sendSynchronousRequest I cant' set delegate, delegate methods just called in case of async calls.

You should really get used to the asynchronous style. The approach with a synchronous call within a dispatch_async call is suboptimal to say the least.

The method sendSynchronousRequest is for beginners and toy apps. IMHO, Apple should really deprecate this method and remove it in the next iOSs.

The method sendAsynchronousRequest:queue:completionHandler: is for demonstration purposes, sample apps, prove of concept, and very simple requests not using authentication and https.

Finally, using the asynchronous style with implementing the delegates is for "serious" and release apps. Any serious app should use https when talking to a dedicated server, unless the server is public and does not support https.

Once your have switched to asynchronous style, there might be an answer to your actual question. However, there is no need to bypass a certificate - rather you will use the certificate as it is used in the release app.



Related Topics



Leave a reply



Submit