Allow unverified ssl certificate in UIWebview
Asked Answered
C

7

28

I'm embedding a website in a UIWebView. During development I have it pointed at localhost. The problem is that whenever it hits a "https://" url it doesn't load. When I load the url in mobile safari I get this popup:

enter image description here

Is there a way to override this with the UIWebView to allow the unverified url?

Cuevas answered 13/1, 2012 at 23:32 Comment(0)
E
8

Nick's answer will keep your app from being accepted by Apple in the App Store and George's answer will fail to load the remainder of a page that has .css or .js or any other secondary downloads. There is a complete answer here that allows the UIWebView to load pages from a site with an untrusted certificate.

Eclectic answered 25/2, 2013 at 19:7 Comment(2)
+1, I just got my app rejected because of using "private api" (allowsAnyHTTPSCertificateForHost method)Doronicum
I mentioned twice in my answer that this solution was to be used to testing purposes only. Pointing your live app at an HTTPS server with an untrusted certificate provides zero security anyway, so you may as well just use HTTP instead.Luster
L
60

If it's just for testing during development you can create a category on NSURLRequest and override the following private method:

#if DEBUG

@implementation NSURLRequest (NSURLRequestWithIgnoreSSL) 

+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
{
    return YES;
}

@end

#endif

Just put this anywhere in one of your .m files (e.g. app delegate), or put it in it's own .m file. You don't need a matching header file.

The #if DEBUG is a precaution to prevent you from accidentally leaving it enabled when you submit to Apple, but if you need it to work in a release build then remove that (and make sure you remember to restore it or remove this category before you submit to Apple).

Luster answered 14/1, 2012 at 0:41 Comment(7)
Could I add a list of trusted hosts in there to check against?Cuevas
You can put whatever logic in the function you want. You could compare the host parameter against an array of trusted hosts and only return YES if it matches. But I don't really see the point if this is only for testing purposes - remember you can't ship an app with this code (unless you want to risk it and hope Apple doesn't notice).Luster
This solution doesn't work for me. When I write this into my code, the app does indeed neglect to throw up an error involving security certificates, but it does not finish loading the page either. I'm not sure what it's doing. I've set up NSLogs in every related method I could find (didFailLoadWithError, didFinishLoading, etc.) and it doesn't ever reach any of them. Is this a problem with my website perhaps?Naught
This doesn't seem to work in the simulator for me so you might want to try on a device.Embrey
This really help me a lot! It works both on my iPad 3 and simulator. Youll just need to create the .h and .m files, which I named as NSURLRequest+Additions.h and NSURLRequest+Additions.m, then I import it into my .m file where I have some NSURLRequest calls in order to override the parent class. Additionally, I have also added these methods,(BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace and (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challengePulsar
Including that #if DEBUG would mean that you don't have to remove it in order to submit to Apple because it is a preprocessor and the code in it wouldn't be included in the compiled code you send to Apple. en.wikipedia.org/wiki/C_preprocessor#Conditional_compilationTrueblood
This plus johnnieb's answer worked for me in the iOS 9 simulator.Interpretive
B
10

Swift 3/4 version for Nick Lockwood answer.

This is just for testing/development purposes:

extension NSURLRequest {
    #if DEBUG
    static func allowsAnyHTTPSCertificate(forHost host: String) -> Bool {
        return true
    }
    #endif
}
Befog answered 27/10, 2016 at 13:21 Comment(1)
@LorenzoB maybe your problem not in certificates?Befog
E
8

Nick's answer will keep your app from being accepted by Apple in the App Store and George's answer will fail to load the remainder of a page that has .css or .js or any other secondary downloads. There is a complete answer here that allows the UIWebView to load pages from a site with an untrusted certificate.

Eclectic answered 25/2, 2013 at 19:7 Comment(2)
+1, I just got my app rejected because of using "private api" (allowsAnyHTTPSCertificateForHost method)Doronicum
I mentioned twice in my answer that this solution was to be used to testing purposes only. Pointing your live app at an HTTPS server with an untrusted certificate provides zero security anyway, so you may as well just use HTTP instead.Luster
S
8

In iOS 9, SSL connections will fail for all invalid or self-signed certificates. This is the default behavior of the new App Transport Security feature in iOS 9.0 or later, and on OS X 10.11 and later.

You can override this behavior in the Info.plist, by setting NSAllowsArbitraryLoads to YES in the NSAppTransportSecurity dictionary. However, I recommend overriding this setting for testing purposes only.

enter image description here

For information see App Transport Technote here.

Strident answered 24/8, 2015 at 18:59 Comment(1)
If you have a self-signed certificate I recommend opening the URL in mobile Safari and accepting the certification first. This should establish trust.Strident
G
3

Using the below two methods we can allow unverified ssl in UIWebview

-(BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace;

-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;

I have answered in detail how to achieve this here

Gorblimey answered 26/12, 2013 at 18:48 Comment(0)
E
2

There's a way to do this legally (by App Store laws at least). When you use the NSURLConnection there are 2 methods that can be used to allow self-signed SSL certificates to be used:

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

If you implement UIWebViewDelegate use the

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;

Return NO to this so that the WebView doesn't load on its own. Then construct an NSURLConnection (which can be used with unsigned certificates via the above link).

Of course the usual SSL recommendations apply here:
-Don't use an unsigned cert on production servers!
-Always surface a warning letting your user decide whether to accept the cert or not.

Embrey answered 4/5, 2012 at 19:54 Comment(0)
A
0

I know its a bit late but it can help others, I found an article to bypass ssl in iOS app, All you need to do is setup your webview and do a post request from application to your server and if you get an ssl error that means you dont have a valid certificate on your server, In order to bypass you have to use webview delegates methonds which are 1.) Can Authenticate Against Protection Space 2.) Should start load with request 3.) Did Receive Authentication Challenge You can copy these function from this URL, For me it works pretty well. Hope it helps

Amalea answered 26/2, 2016 at 15:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.