2

I have https url with self-sign certication in UIWEBView ,but it does not work.

Error is NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)...

how can I to allow any certication in uiwebview by swift

Do you have any idea that fix this problem?

3 Answers 3

3

i find a way to do this,but i think this is not a good way.

step 1------use NSURLConnection in override func viewDidLoad(){} section request = NSURLRequest(URL:url)

 let urlConnection:NSURLConnection = NSURLConnection(request: request, delegate: self)! 

step 2------ use the NSURLConnection delegate to

func connection(connection: NSURLConnection, didFailWithError error: NSError){ println("didFailWithError") } func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace) -> Bool{ println("canAuthenticateAgainstProtectionSpace") //return [protectionSpace.authenticationMethodisEqualToString:NSURLAuthenticationMethodServerTrust]; return true } func connection(connection: NSURLConnection, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge){ println("did autherntcationchallenge = \(challenge.protectionSpace.authenticationMethod)") //if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust && challenge.protectionSpace.host == "myDomain.com" { if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { println("send credential Server Trust") let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust) challenge.sender.useCredential(credential, forAuthenticationChallenge: challenge) }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic{ println("send credential HTTP Basic") var defaultCredentials: NSURLCredential = NSURLCredential(user: "username", password: "password", persistence:NSURLCredentialPersistence.ForSession) challenge.sender.useCredential(defaultCredentials, forAuthenticationChallenge: challenge) }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM{ println("send credential NTLM") if challenge.previousFailureCount > 0 { //如果连续两次验证未通过,则终止, 还需要返回自定义出错界面 //handle bad credentials scenario } var defaultCredentials: NSURLCredential = NSURLCredential(user: "username", password: "password", persistence:NSURLCredentialPersistence.ForSession) challenge.sender.useCredential(defaultCredentials, forAuthenticationChallenge: challenge) } } else{ challenge.sender.performDefaultHandlingForAuthenticationChallenge!(challenge) } //challenge.sender.performDefaultHandlingForAuthenticationChallenge!(challenge) //challenge.sender.continueWithoutCredentialForAuthenticationChallenge(challenge) } /* func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge) { }*/ func connection(connection: NSURLConnection, didCancelAuthenticationChallenge challenge: NSURLAuthenticationChallenge){ println("didCancelAuthenticationChallenge") } /* - (void)connection: (NSURLConnection *)connection willSendRequestForAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge { [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; }*/ func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse){ println("-----received response"); // remake a webview call now that authentication has passed ok. //_authenticated =YES; //[_webloadRequest:_request]; webView.loadRequest(request) // Cancel the URL connection otherwise we double up (webview + url connection, same url = no good!) //[_urlConnectioncancel]; } 

it can work

sorry for my poor english skill

Sign up to request clarification or add additional context in comments.

3 Comments

I get to the point at which I receive a response and try to load the request again, but it does not load on the view.
This is great, this is how I've always done it in both Swift and Objective C no problems
I've always seen loading the request in connectionDidFinishLoading though instead of didReceiveResponse
1

This is the Swift 3 approach...

import UIKit import Security class ViewController: UIViewController, UIWebViewDelegate, NSURLConnectionDelegate { @IBOutlet weak var webView: UIWebView! var loadingUnvalidatedHTTPSPage:Bool! var connection:NSURLConnection! let path = "https://my.url.com.mx" override func viewDidLoad() { super.viewDidLoad() webView.delegate = self webView.scalesPageToFit = true webView.contentMode = .scaleAspectFit let requestObj = NSURLRequest.init(url: URL(string: path)!, cachePolicy: NSURLRequest.CachePolicy.useProtocolCachePolicy, timeoutInterval: 10.0) let conn:NSURLConnection = NSURLConnection(request: requestObj as URLRequest, delegate: self)! conn.start() self.loadingUnvalidatedHTTPSPage = true webView.loadRequest(requestObj as URLRequest) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } // MARK - DELEGATE METHODS WEBVIEW private func webView(webView: UIWebView!, didFailLoadWithError error: NSError!) { print("Webview fail with error \(error)"); if(error.domain == NSURLErrorDomain){ if (error.code == NSURLErrorServerCertificateHasBadDate || error.code == NSURLErrorServerCertificateUntrusted || error.code == NSURLErrorServerCertificateHasUnknownRoot || error.code == NSURLErrorServerCertificateNotYetValid) { print("\n ---- :C ....") } } } private func webView(webView: UIWebView!, shouldStartLoadWithRequest request: NSURLRequest!, navigationType: UIWebViewNavigationType) ->Bool{ print("Webview iniciando"); if (self.loadingUnvalidatedHTTPSPage!) { self.connection = NSURLConnection(request: request as URLRequest, delegate: self) self.connection.start(); return false; } return true; } private func webViewDidStartLoad(webView: UIWebView!) { print("Webview started Loading") } private func webViewDidFinishLoad(webView: UIWebView!) { print("Webview did finish load") } // MARK - NSURLConnectionDelegate methods func connection(_ connection: NSURLConnection, willSendRequestFor challenge: URLAuthenticationChallenge) { let trust:SecTrust = challenge.protectionSpace.serverTrust!; let cred:URLCredential = URLCredential(trust: trust) challenge.sender?.use(cred, for: challenge) } func connection(_ connection: NSURLConnection, NSURLConnection response:URLResponse){ let requestObj:NSURLRequest = NSURLRequest(url: URL(string: path)!, cachePolicy: NSURLRequest.CachePolicy.returnCacheDataElseLoad, timeoutInterval: 20.0) self.loadingUnvalidatedHTTPSPage = false self.webView.loadRequest(requestObj as URLRequest) self.connection.cancel() } } 

Don't forget to set "Allow Arbitrary Loads" = YES in your .plist file.

<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> 

Comments

-1

You need to bundle your cert with your app. Then, the cert will end up being trusted by app networking components, including your web view.

2 Comments

i want to ignore the risk, is there a simple way to connect https like http
I don't think you can. The underlying network machinery checks certs when establishing an HTTPS connection. I know how to deal with that if I am writing low level Java code, but I don't think a UIWebView gives you a way to do that.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.