Swift 3 NSURLSession/NSURLConnection 使用身份验证连接到站点时 HTTP 加载失败
Swift 3 NSURLSession/NSURLConnection HTTP load failed when connecting to a site with authentication
我以前见过这个错误,似乎补救措施是将信息添加到 .plist 文件。我已经尝试了我见过的每一个:
我的程序仍然导致抛出相同的错误:
2017-05-08 08:29:37.781075-0400 xxxx[3256:408961] [] nw_coretls_callback_handshake_message_block_invoke_3 tls_handshake_continue: [-9812]
2017-05-08 08:29:37.781 xxxx[3256:408982] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
我的相关代码在这里:
let username = "xxxx"
let password = "xxxx"
let loginString = String(format: "%@:%@", username, password)
let loginData = loginString.data(using: String.Encoding.utf8)!
let base64LoginString = loginData.base64EncodedString()
let baseUrl = "https://xxxx"
var request = URLRequest(url: URL(string: baseUrl)! as URL)
let baseUrl = "server i want.xml"
let request = NSMutableURLRequest(url: NSURL(string: baseUrl)! as URL)
request.httpMethod = "POST"
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
let session = URLSession.shared
var err: NSError?
let task = session.dataTask(with: request as URLRequest) {
(data, response, error) in
if data == nil {
print("dataTaskWithRequest error: \(err)")
return
}
let xml = SWXMLHash.parse(data!)
let serialNumFromXML = xml["mobile_devices"]["mobile_device"]["serial_number"].element?.text
func urlSession(
_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
{
completionHandler(
.useCredential,
URLCredential(trust: challenge.protectionSpace.serverTrust!))
}
我看过可能跟证书有关,但是我不能换服务器,因为我不负责,所以我拿不到合适的证书。除了更改 plist 之外,还有更多吗?
我的 plist 文件具有允许任意加载和我的 XML 文件所在域的异常域。
我可以获取测试文件的内容,例如 https://www.w3schools.com/xml/note.xml,但我需要的文件在 username/password "Authentication Required" 弹出窗口后面。
我也试过 Alamofire 库,同样的事情发生了:
nw_coretls_callback_handshake_message_block_invoke_3 tls_handshake_continue: [-9807]
2017-05-08 09:42:08.452 xxx[6128:888398] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
好吧,我不知道如何解决这个问题,但我发现 Alamofire 可以用来做我需要的事情。这是一个用于库存管理的本地项目,因此我并不担心绕过证书的安全性。我的代码在这里:
Manager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: URLSession.AuthChallengeDisposition = .performDefaultHandling
var credential: URLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, let trust = challenge.protectionSpace.serverTrust {
disposition = URLSession.AuthChallengeDisposition.useCredential
credential = URLCredential(trust: trust)
} else {
if challenge.previousFailureCount > 0 {
disposition = .cancelAuthenticationChallenge
} else {
credential = Manager.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)
if credential != nil {
disposition = .useCredential
}
}
}
return (disposition, credential)
}
private var Manager: Alamofire.SessionManager = {
// Create the server trust policies
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"https://SERVER:PORT": .disableEvaluation
]
// Create custom manager
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
let manager = Alamofire.SessionManager(
configuration: URLSessionConfiguration.default,
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
let sessionManager = SessionManager(
serverTrustPolicyManager: ServerTrustPolicyManager(
policies: ["https://SERVER:PORT": .disableEvaluation]
)
)
return manager
}()
open class MyServerTrustPolicyManager: ServerTrustPolicyManager {
// Override this function in order to trust any self-signed https
open override func serverTrustPolicy(forHost host: String) -> ServerTrustPolicy? {
return ServerTrustPolicy.disableEvaluation
}
}
我以前见过这个错误,似乎补救措施是将信息添加到 .plist 文件。我已经尝试了我见过的每一个:
我的程序仍然导致抛出相同的错误:
2017-05-08 08:29:37.781075-0400 xxxx[3256:408961] [] nw_coretls_callback_handshake_message_block_invoke_3 tls_handshake_continue: [-9812] 2017-05-08 08:29:37.781 xxxx[3256:408982] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
我的相关代码在这里:
let username = "xxxx"
let password = "xxxx"
let loginString = String(format: "%@:%@", username, password)
let loginData = loginString.data(using: String.Encoding.utf8)!
let base64LoginString = loginData.base64EncodedString()
let baseUrl = "https://xxxx"
var request = URLRequest(url: URL(string: baseUrl)! as URL)
let baseUrl = "server i want.xml"
let request = NSMutableURLRequest(url: NSURL(string: baseUrl)! as URL)
request.httpMethod = "POST"
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
let session = URLSession.shared
var err: NSError?
let task = session.dataTask(with: request as URLRequest) {
(data, response, error) in
if data == nil {
print("dataTaskWithRequest error: \(err)")
return
}
let xml = SWXMLHash.parse(data!)
let serialNumFromXML = xml["mobile_devices"]["mobile_device"]["serial_number"].element?.text
func urlSession(
_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
{
completionHandler(
.useCredential,
URLCredential(trust: challenge.protectionSpace.serverTrust!))
}
我看过可能跟证书有关,但是我不能换服务器,因为我不负责,所以我拿不到合适的证书。除了更改 plist 之外,还有更多吗?
我的 plist 文件具有允许任意加载和我的 XML 文件所在域的异常域。
我可以获取测试文件的内容,例如 https://www.w3schools.com/xml/note.xml,但我需要的文件在 username/password "Authentication Required" 弹出窗口后面。
我也试过 Alamofire 库,同样的事情发生了:
nw_coretls_callback_handshake_message_block_invoke_3 tls_handshake_continue: [-9807] 2017-05-08 09:42:08.452 xxx[6128:888398] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
好吧,我不知道如何解决这个问题,但我发现 Alamofire 可以用来做我需要的事情。这是一个用于库存管理的本地项目,因此我并不担心绕过证书的安全性。我的代码在这里:
Manager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: URLSession.AuthChallengeDisposition = .performDefaultHandling
var credential: URLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, let trust = challenge.protectionSpace.serverTrust {
disposition = URLSession.AuthChallengeDisposition.useCredential
credential = URLCredential(trust: trust)
} else {
if challenge.previousFailureCount > 0 {
disposition = .cancelAuthenticationChallenge
} else {
credential = Manager.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)
if credential != nil {
disposition = .useCredential
}
}
}
return (disposition, credential)
}
private var Manager: Alamofire.SessionManager = {
// Create the server trust policies
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"https://SERVER:PORT": .disableEvaluation
]
// Create custom manager
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
let manager = Alamofire.SessionManager(
configuration: URLSessionConfiguration.default,
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
let sessionManager = SessionManager(
serverTrustPolicyManager: ServerTrustPolicyManager(
policies: ["https://SERVER:PORT": .disableEvaluation]
)
)
return manager
}()
open class MyServerTrustPolicyManager: ServerTrustPolicyManager {
// Override this function in order to trust any self-signed https
open override func serverTrustPolicy(forHost host: String) -> ServerTrustPolicy? {
return ServerTrustPolicy.disableEvaluation
}
}