Allow Unverified Ssl Certificates in Wkwebview

Allow unverified ssl certificate in UIWebview

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.

Allow self signed certificates using WKWebView

You have to provide ATS (App Transport Security) exceptions in Info.plist in order to override the certificate verification logic. While you accept the certificate, the ATS system is still rejecting it. See NSAppTransportSecurity in the Information Property List Key Reference for details. Generally you'd want NSAllowsArbitraryLoadsInWebContent for your specific domain for this usage.

Keep in mind:

App Store Review for ATS

Your use of certain App Transport Security (ATS) keys triggers additional App Store review for your app, and requires you to provide justification. These keys are:

  • NSAllowsArbitraryLoads
  • NSAllowsArbitraryLoadsForMedia
  • NSAllowsArbitraryLoadsInWebContent
  • NSExceptionAllowsInsecureHTTPLoads
  • NSExceptionMinimumTLSVersion

Some examples of justifications eligible for consideration are:

  • Must connect to a server managed by another entity that does not support secure connections
  • Must support connecting to devices that cannot be upgraded to use secure connections, and that must be accessed via public host names
  • Must provide embedded web content from a variety of sources, but cannot use a class supported by the NSAllowsArbitraryLoadsInWebContent key
  • App loads media content that is encrypted and that contains no personalized information

When submitting your app to the App Store, provide sufficient information for the App Store to determine why your app cannot make secure connections by default.

As a general rule, it's easier to get a commercial certificate than to manage the exceptions for managing your own root certificate (which is what "self-signed" certs really are).

IOS wkwebview using self-assigned Cert

Your delegate method signature doesn't quite match. Try this:

func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
let cred = URLCredential.init(trust: challenge.protectionSpace.serverTrust!)
completionHandler(.useCredential, cred)
}

UIWebView to view self signed websites (No private api, not NSURLConnection) - is it possible?

Finally I got it!

What you can do is this:

Initiate your request using UIWebView as normal. Then - in webView:shouldStartLoadWithRequest - we reply NO, and instead start an NSURLConnection with the same request.

Using NSURLConnection, you can communicate with a self-signed server, as we have the ability to control the authentication through the extra delegate methods which are not available to a UIWebView. So using connection:didReceiveAuthenticationChallenge we can authenticate against the self signed server.

Then, in connection:didReceiveData, we cancel the NSURLConnection request, and start the same request again using UIWebView - which will work now, because we've already got through the server authentication :)

Here are the relevant code snippets below.

Note: Instance variables you will see are of the following type:

UIWebView *_web
NSURLConnection *_urlConnection
NSURLRequest *_request

(I use an instance var for _request as in my case it's a POST with lots of login details, but you could change to use the request passed in as arguments to the methods if you needed.)

#pragma mark - Webview delegate

// Note: This method is particularly important. As the server is using a self signed certificate,
// we cannot use just UIWebView - as it doesn't allow for using self-certs. Instead, we stop the
// request in this method below, create an NSURLConnection (which can allow self-certs via the delegate methods
// which UIWebView does not have), authenticate using NSURLConnection, then use another UIWebView to complete
// the loading and viewing of the page. See connection:didReceiveAuthenticationChallenge to see how this works.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
{
NSLog(@"Did start loading: %@ auth:%d", [[request URL] absoluteString], _authenticated);

if (!_authenticated) {
_authenticated = NO;

_urlConnection = [[NSURLConnection alloc] initWithRequest:_request delegate:self];

[_urlConnection start];

return NO;
}

return YES;
}

#pragma mark - NURLConnection delegate

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
{
NSLog(@"WebController Got auth challange via NSURLConnection");

if ([challenge previousFailureCount] == 0)
{
_authenticated = YES;

NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];

[challenge.sender useCredential:credential forAuthenticationChallenge:challenge];

} else
{
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
{
NSLog(@"WebController received response via NSURLConnection");

// remake a webview call now that authentication has passed ok.
_authenticated = YES;
[_web loadRequest:_request];

// Cancel the URL connection otherwise we double up (webview + url connection, same url = no good!)
[_urlConnection cancel];
}

// We use this method is to accept an untrusted site which unfortunately we need to do, as our PVM servers are self signed.
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

I hope this helps others with the same issue I was having!



Related Topics



Leave a reply



Submit