Ignoring Invalid Server Certificates with UIWebView [duplicate]
We have an iOS app that uses a UIWebView to display content. We load it up with data with code that looks like this:
NSURL *url = [NSURL URLWithString:myURLString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_webView setDelegate:self];
[_webView loadRequest:request];
This used to work fine with HTTP requests, but now we are using HTTPS against a server with a self-signed SSL certificate. When the above is run, the webView:didFailLoadWithError:
delegate method gets called, with this error:
The certificate for this server is invalid. You might be connecting to a server that is pretending to be "blah.blah.blah.com" which could put your confidential information at risk."
I would like to simply ignore the invalid certificate and go on with the request, as one can do in Mobile Safari.
I have seen how to work around this issue when using NSURLConnection
(see HTTPS request on old iphone 3g, for example), but what can one do with a UIWebView
?
I imagine that I could rework the code so that it uses NSURLConnection
to make the requests and then puts the results into the web view by calling its loadHTMLString:baseURL:
method, but that's going to get complicated when the pages have images, CSS, JavaScript, and so on. Is there an easier way?
Please note: This API is currently unsupported, and should really only be used in a safe testing environment. For further details, take a look at this CocoaNetics article.
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
will allow you to ignore certificate errors. You will also need to add the following to the beginning of your file to grant you access to these private APIs:
@interface NSURLRequest (DummyInterface)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host;
@end
Just so everyone knows... the above use of hidden interfaces WILL NOT BE ACCEPTED BY APPLE. They look for use of private APIs and it is NOT an acceptable solution. So, please do not go posting the solution described above around as THE way to fix it because, although it works, it will buy you a rejection in the AppStore. That makes it useless.
What follows is the ACCEPTABLE method of ignoring invalid server certificates. You need to use NSURLConnection and load the data for the webpage manually like so:
.
.
.
//Create a URL object.
url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:requestObj delegate:self];
[connection start];
}
And then, in your 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])
{
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}
else
{
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[resultData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *htmlString = [[NSString alloc] initWithBytes:[resultData bytes] length:[resultData length] encoding:NSUTF8StringEncoding];
[webView loadHTMLString:htmlString baseURL:url];
}
@end
Where resultData is an NSMutableData you instantiated earlier and where url and urlAddress are both things you've instantiated and filled in elsewhere.
Unfortunately, I currently don't know a way to get the actual UIWebView to load a page directly without having a valid certificate.
Yours, GC
It turns out that once the site is authenticated by a cancelled NSURLConnection, the UIWebView can make requests to the site. There is a complete explanation here.
As far as I know, that isn't possible with just UIWebView
. As I understand it, you need to use NSURLConnection
to handle all the HTTP/HTTPS mojo and then feed its results to the UIWebView
via -loadHtmlString:baseURL:
or -loadData:MIMEType:textEncodingName:baseURL:
.
精彩评论