xcode 使用 NSURLSession (swift2,xcode7,ios9) 连接到证书无效的服务器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33128240/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Connect to a Server with Invalid Certificate using NSURLSession (swift2,xcode7,ios9)
提问by cakes88
I'm using Xcode 7, Swift 2, and iOS9. I want to connect to a web service using NSURLSession but I get the following error when I try to connect:
我使用的是 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?,
Here is my code:
这是我的代码:
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)
});
I've looked into NSURLAuthenticationChallenge
but I can't seem to figure that out with the code I currently have in place. So my question is how can I connect to the server anyway? I've already tried adding the domain to my NSAppTransportSecurity
in Info.plist but that did not work. Turning on NSAllowsArbitraryLoads
didn't work either. Any help would be appreciated.
我已经调查过了,NSURLAuthenticationChallenge
但我似乎无法用我目前拥有的代码来解决这个问题。所以我的问题是我怎样才能连接到服务器?我已经尝试将域添加到我NSAppTransportSecurity
的 Info.plist 中,但这没有用。开机NSAllowsArbitraryLoads
也没有用。任何帮助,将不胜感激。
回答by FractalDoctor
Take a look at this article.Shipping an App With App Transport Securityparticularly the sections about self-signed certificates.
看看这篇文章。使用 App Transport Security 运送应用程序,特别是有关自签名证书的部分。
You'll most likely need the delegate method of the form,
您很可能需要表单的委托方法,
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
completionHandler(
.UseCredential,
NSURLCredential(trust: challenge.protectionSpace.serverTrust!)
)
}
Adding this to my own comms class that uses NSURLSession fixed the issue.
将此添加到我自己的使用 NSURLSession 的通信类修复了该问题。
回答by Debaditya Sarkar
When creating the URL Session, use the initializer, that sets the delegate along with the configuration, like below:
创建 URL 会话时,使用初始化器,它设置委托和配置,如下所示:
let urlSession = URLSession(configuration: urlSessionConfiguration, delegate: self, delegateQueue: nil)
Then, implement the following delegate method, it should work.
然后,实现以下委托方法,它应该可以工作。
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
let urlCredential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
completionHandler(.useCredential, urlCredential)
}
However, it is very important to note, that this is a security issue, and we should not be trying to connect to servers with invalid certificates.
但是,需要注意的是,这是一个安全问题,我们不应该尝试连接到带有无效证书的服务器。
回答by Marcelo Pontes Machado
open your info.plist as a source code Add following:
打开您的 info.plist 作为源代码添加以下内容:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
This should help.
这应该有帮助。
回答by Revanth Matha
I received the error "The certificate for this server is invalid. You might be connecting to a server that is pretending to be "www.yoururl.com" which could put your confidential information at risk."
我收到错误消息“此服务器的证书无效。您可能正在连接到一个伪装成“www.yoururl.com”的服务器,这可能会使您的机密信息处于危险之中。
I solved this by having doing this in my httpclient file. The following code will ignore the authentication request completely.
我通过在我的 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
)
}
Also not sure if it impacted the above but In my info.plist I had "Allow Transport Security Settings" & the child key-value option "Allow Arbitrary Loads" which I set to YES.
也不确定它是否影响了上述内容,但在我的 info.plist 中,我有“允许传输安全设置”和我设置为“是”的子键值选项“允许任意加载”。
回答by kiran kumar
For SWIFT 4:
对于 SWIFT 4:
func URLSession(session: URLSession, didReceiveChallenge challenge: URLAuthenticationChallenge, completionHandler: (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
completionHandler(
.useCredential,
URLCredential(trust: challenge.protectionSpace.serverTrust!)
)
}