使用NSURLSession(swift2、xcode7、ios9)连接到具有无效证书的服务器

使用NSURLSession(swift2、xcode7、ios9)连接到具有无效证书的服务器,xcode,swift,swift2,ios9,xcode7,Xcode,Swift,Swift2,Ios9,Xcode7,我使用的是Xcode 7、Swift 2和iOS9。我想使用NSURLSession连接到web服务,但在尝试连接时出现以下错误: 2015-10-13 16:07:33.595 XCTRunner[89220:4520715] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) 2015-10-13 16:07:33.604 XCTRunner[89220:4520571] Error w

我使用的是Xcode 7、Swift 2和iOS9。我想使用NSURLSession连接到web服务,但在尝试连接时出现以下错误:

2015-10-13 16:07:33.595 XCTRunner[89220:4520715] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
2015-10-13 16:07:33.604 XCTRunner[89220:4520571] Error with connection, details: Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “domainapi.com” which could put your confidential information at risk." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x7fac7b6facc0>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?,
2015-10-13 16:07:33.595 XCTRunner[89220:4520715]NSURLSession/NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9813)
2015-10-13 16:07:33.604 XCTRunner[89220:4520571]连接错误,详细信息:错误域=NSURLErrorDomain Code=-1202“此服务器的证书无效。您可能正在连接假装为“domainapi.com”的服务器,这可能会使您的机密信息面临风险。”UserInfo={nSurlerErrorFailingUrlPeerTrustErrorKey=,NSLocalizedRecoverySuggestion=是否仍要连接到服务器?,
这是我的密码:

func request( dataPost : String, successHandler: (response: String) -> Void)-> String {
        let destination:String =  "https://domainapi.com:8743/WebService/sendData"
        let request = NSMutableURLRequest(URL: NSURL(string: destination as String)!)
        request.HTTPMethod = "POST"
        let postString = dataPost
        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
        request.setValue("0", forHTTPHeaderField: "Content-Length")
        request.setValue("application/xml", forHTTPHeaderField: "Content-Type")
        request.setValue("gzip,deflate", forHTTPHeaderField: "Accept-Encoding")
        request.setValue("Keep-Alive", forHTTPHeaderField: "Connection")
        NSLog("Body is: %@", request.HTTPBody!)
        NSLog("Request is: %@", request.allHTTPHeaderFields!)
        NSLog("URL is: %@", destination)

        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in


            if error != nil {
                NSLog("Error with connection, details: %@", error!)
                return
            }

            let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)

            successHandler(response: responseString as String!);
            NSLog("Data received: %@", data!)

        }

        task.resume()
        return "worked"
    }
    func viewDidLoad() {
        let dataPost : String = "<webservices>xml data sending</webservices>"
        request(dataPost, successHandler: {
            (response) in
            let text = response
            print(text)
        });
func请求(dataPost:String,successHandler:(响应:String)->Void)->String{
让目标:字符串=”https://domainapi.com:8743/WebService/sendData"
let request=NSMutableURLRequest(URL:NSURL(字符串:目标为字符串)!)
request.HTTPMethod=“POST”
让postString=dataPost
request.HTTPBody=postString.dataUsingEncoding(NSUTF8StringEncoding)
request.setValue(“0”,用于HttpHeaderField:“内容长度”)
request.setValue(“应用程序/xml”,用于HttpHeaderField:“内容类型”)
setValue(“gzip,deflate”,用于HttpHeaderField:“接受编码”)
request.setValue(“保持活动”,用于HttpHeaderField:“连接”)
NSLog(“正文为:%@”,request.HTTPBody!)
NSLog(“请求为:%@”,Request.allHTTPHeaderFields!)
NSLog(“URL为%@”,目的地)
让task=NSURLSession.sharedSession().dataTaskWithRequest(请求){
数据、响应、错误
如果错误!=nil{
NSLog(“连接错误,详细信息:%@”,错误!)
返回
}
让responseString=NSString(数据:data!,编码:NSUTF8StringEncoding)
successHandler(响应:responseString!);
NSLog(“收到的数据:%@”,数据!)
}
task.resume()
返回“已工作”
}
func viewDidLoad(){
let dataPost:String=“xml数据发送”
请求(dataPost,successHandler:{
(答复)在
让文本=响应
打印(文本)
});

我已经研究了
nsurauthenticationchallenge
,但用我目前的代码,我似乎无法解决这个问题。所以我的问题是如何连接到服务器?我已经尝试在Info.plist中将域添加到我的
NSAppTransportSecurity
,但没有成功。打开
nsallowarbirylo广告也不起作用。任何帮助都将不胜感激。

打开你的info.plist作为源代码 添加以下内容:

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

这应该会有所帮助。

看看这篇文章,特别是关于自签名证书的部分

您很可能需要表单的委托方法

func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
    completionHandler(
        .UseCredential, 
        NSURLCredential(trust: challenge.protectionSpace.serverTrust!)
    )
}

将其添加到使用NSURLSession的我自己的comms类中修复了该问题。

创建URL会话时,请使用初始值设定项,该初始值设定项将委托与配置一起设置,如下所示:

let urlSession = URLSession(configuration: urlSessionConfiguration, delegate: self, delegateQueue: nil)
然后,实现下面的委托方法,它应该可以工作

func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    let urlCredential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
    completionHandler(.useCredential, urlCredential)
}
但是,需要注意的是,这是一个安全问题,我们不应该试图连接到具有无效证书的服务器。

对于SWIFT 4:

func URLSession(session: URLSession, didReceiveChallenge challenge: URLAuthenticationChallenge, completionHandler: (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    completionHandler(
        .useCredential,
        URLCredential(trust: challenge.protectionSpace.serverTrust!)
    )
}
我收到错误“此服务器的证书无效。您可能正在连接假装为“www.yoururl.com”的服务器,这可能会使您的机密信息面临风险。”

我在httpclient文件中这样做解决了这个问题。下面的代码将完全忽略身份验证请求

var session: URLSession?

session = URLSession(configuration: sessionConfiguration(), delegate: self, delegateQueue: nil)

private func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: (URLSession.AuthChallengeDisposition) -> Void) {
            completionHandler(
                .cancelAuthenticationChallenge
            )
        }

也不确定它是否影响了上述内容,但在我的info.plist中,我有“允许传输安全设置”和子键值选项“允许任意加载”,我将其设置为“是”。

许多答案几乎都在那里,但不完全在那里。下面是我在Xcode 12.4上的工作原理

在我的课堂上

let会话:URLSession
让sessionDelegate:HTTPRequestDelegate
私有init(){
let configuration=URLSessionConfiguration.default
//更多配置设置
// ...
sessionDelegate=HTTPRequestDelegate()
session=URLSession(配置:配置,
代表:会议代表,
委派队列:无)
}
其中:

公共类HTTPRequestDelegate:NSObject,URLSessionDelegate
{
//接受两次挑战,第二次挑战。protectionSpace.serverTrust为零,但有效!
公共函数urlSession(usession:urlSession,
didReceive质询:URLAuthenticationChallenge,
completionHandler:(URLSession.AuthChallengeDisposition,URLCredential?->Void){
打印(“在无效的证书完成处理程序中”)
如果challenge.protectionSpace.serverTrust!=nil{
completionHandler(.useCredential,URLCredential(信任:challenge.protectionSpace.serverTrust!))
}否则{
completionHandler(.useCredential,nil)
}
}
}

在SO上查看此问题:@ZoffDino正在使用iOS8中不推荐使用的NSURLConnection。如果可能的话,我想使用NSURLSession。AFNetworking库对此有很好的支持,我建议您检查一下。我不认为这有什么帮助,因为您实际上只是绕过了应用程序与之通信的IP地址,而不是其他地址服务器证书怎么办?@Marcelo:NSAllowsArbitaryLoads key设置为true时将允许访问所有不安全的URL。那么,为了安全起见,使用CER文件有什么意义呢?我补充道