Swift 2 – Xcode 7.0无法使用不可信的SSL证书访问HTTPS站点

专家,我是IOS 9 / XCODE 7 / Swift 2开发工具包的初学者

我试图创build一个简单的路由到HTTPS协议Web应用程序的iOS应用程序。 以下是我在ViewController.swift代码

 import UIKit class ViewController: UIViewController { @IBOutlet var myWebView: UIWebView! /** * Function to Display the Web Application initial URL */ func loadAppURL(){ let siteAddress = "https://domain:8443/path/to/page" let url = NSURL (string: siteAddress) let urlRequest = NSURLRequest(URL: url!) myWebView.loadRequest(urlRequest) } override func viewDidLoad() { super.viewDidLoad() loadAppURL() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } 

在构build我的应用程序时,显示下面的错误消息

2015-10-01 01:05:13.879 Web Page Tester [2947:31838] NSURLSession / NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9807)

如果我尝试使用“ http://www.apple.com ”构build我的应用程序而不是“ https:// domain:8443 / path / to / page ”,它的工作正常。

我可以在Safari中访问我的Web应用程序,并要求接受安全风险。 我接受它,我可以访问我的应用程序。

指导我解决我的问题,提前致谢。

最后我修好了

Xcode将默认拒绝来自服务器的不可信自签名证书。

我们可以覆盖这个使用NSURLConnection并可以与自签名服务器通信,因为我们有能力通过UIWebView不可用的其他委托方法来控制身份validation。 所以使用connection:didReceiveAuthenticationChallenge我们可以对自签名服务器进行身份validation。

参考文献NSURLAuthenticationChallenge Docs ,@Lilo Lu的问题

我在下面的步骤中解决了我的问题
第1步:在viewController.swift的viewDidLoad()方法中定义一个NSURLConnection ,如下所示

  override func viewDidLoad() { super.viewDidLoad() let siteAddress = "https://domain:8443/path/to/page" let url = NSURL (string: siteAddress) let urlRequest = NSURLRequest(URL: url!) let urlConnection:NSURLConnection = NSURLConnection(request: request, delegate: self)! myWebView.loadRequest(urlRequest) } 

第2步:使用NSURLConnection委托方法

  func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace) -> Bool{ print("canAuthenticateAgainstProtectionSpace method Returning True") return true } func connection(connection: NSURLConnection, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge){ print("did autherntcationchallenge = \(challenge.protectionSpace.authenticationMethod)") if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { print("send credential Server Trust") let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!) challenge.sender!.useCredential(credential, forAuthenticationChallenge: challenge) }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic{ print("send credential HTTP Basic") let defaultCredentials: NSURLCredential = NSURLCredential(user: "username", password: "password", persistence:NSURLCredentialPersistence.ForSession) challenge.sender!.useCredential(defaultCredentials, forAuthenticationChallenge: challenge) }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM{ print("send credential NTLM") } else{ challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge) } } 

这工作!

您可以将以下内容添加到您的plist中

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

在这里输入图像说明

在Swift 3。

第1步。添加NSURLConnectionDelegate到你的viewcontroller,覆盖方法。

 class ViewController: UIViewController, NSURLConnectionDelegate { 

第2步。覆盖viewDidLoad

 override func viewDidLoad() { super.viewDidLoad() let siteAddress = "https://mysiteaddress" let url = URL(string: siteAddress) let urlRequest = URLRequest(url: url!) let urlConnection:NSURLConnection = NSURLConnection(request: urlRequest, delegate: self)! webView.loadRequest(urlRequest) } 

步骤3覆盖canAuthenticateAgainstProtectionSpace并接受didReceive challenge

 func connection(_ connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: URLProtectionSpace) -> Bool { print("\ncanAuthenticateAgainstProtectionSpace method Returning True\n") return true } func connection(_ connection: NSURLConnection, didReceive challenge: URLAuthenticationChallenge) { print("did autherntcationchallenge = \(challenge.protectionSpace.authenticationMethod)") if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { print("\nsend credential Server Trust\n") let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!) challenge.sender!.use(credential, for: challenge) }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic{ print("send credential HTTP Basic") let defaultCredentials: URLCredential = URLCredential(user: "user", password: "password", persistence:URLCredential.Persistence.forSession) challenge.sender!.use(defaultCredentials, for: challenge) }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM{ print("\nsend credential NTLM\n") } else{ challenge.sender!.performDefaultHandling!(for: challenge) } } 

感谢纳瓦斯Basheer的原始解决scheme! 为我节省了很多时间

1-创build类别“NSURLRequestCategory” – >将这个类别导入到由xcode创build的桥接文件之后(不要忘记让xCode创build一个,如果你没有的话),并把这个代码:

  @implementation NSURLRequest (NSURLRequestCategory) + (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host { return YES; } @end 

正常创build您的加载请求UIWebView:

 webView.delegate = self let myURL = URL(string: Constants.URL_DOMAINE) let request = URLRequest(url: myURL!) webView.loadRequest(request) 

Enjoyyy:D

编辑Info.plist,添加:

  1. 应用传输安全设置
  2. 允许任意负载,值为YES

它是为我工作,XCode 7.3