如何在uiwebview(swift)中调用https url?

时间:2015-03-14 08:48:51

标签: swift ssl https uiwebview

我在UIWEBView中使用自签名证书的https网址,但它不起作用。

  

错误是NSURLConnection / CFURLConnection HTTP加载失败   (kCFStreamErrorDomainSSL,-9813)...

如何通过swift

在uiwebview中允许任何认证

你有什么想法解决这个问题吗?

3 个答案:

答案 0 :(得分:3)

我找到了一种方法,但我认为这不是一个好方法。

步骤1 ------在override func viewDidLoad(){}部分使用NSURLConnection  request = NSURLRequest(URL:url)

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

步骤2 ------使用NSURLConnection委托

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];
}

它可以工作

抱歉,我的英语技能很差

答案 1 :(得分:1)

这是Swift 3方法......

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()
    }

}

不要忘记在.plist文件中设置“允许任意载入”= YES。

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

答案 2 :(得分:-1)

您需要将证书与您的应用捆绑在一起。然后,证书最终将受到应用程序网络组件的信任,包括您的Web视图。