我正在尝试从URL下载PDF。
private func downloadSessionWithFileURL(_ url: URL){
var request = URLRequest(url: url)
request.addValue("gzip, deflate", forHTTPHeaderField: "Accept-Encoding")
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig, delegate: self, delegateQueue: nil)
session.downloadTask(with: request).resume()
}
这将调用其委托方法
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
if challenge.previousFailureCount > 0 {
completionHandler(Foundation.URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
}
if let serverTrust = challenge.protectionSpace.serverTrust {
completionHandler(Foundation.URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust: serverTrust))
} else {
print("unknown state. error: \(String(describing: challenge.error))")
}
}
URLAuthenticationChallenges protectionSpace始终为serverTrust。当尝试访问PDF的URL时,它会将用户重定向到登录屏幕。我还以为会有另一个调用
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
要求用户输入他们的凭据,但没有。因此下载任务尝试下载重定向URL的内容,这是一个登录屏幕。
我的问题是。
1.什么会触发用户名和密码的URLAuthenticationChallenge。它是HTML中的特定头值吗?
1.对于来自服务器的用户名和密码请求,我应该期待哪个URLAuthenticationChallenge protectionSpace。
2条答案
按热度按时间4uqofj5v1#
有两种不同的委托协议:用于URLSession本身及其任务。
URL会话委托具有:
public func urlSession(_:didReceive:completionHandler:)
URL会话任务委托具有:public func urlSession(_:task:didReceive:completionHandler:)
URLSessionDelegate用于服务器信任问题(例如,在通过Charles或其他代理运行时允许SSL信任)。URLSessionTaskDelegate用于单个任务的身份验证。
因此,要获得身份验证挑战,请将以下代码添加到类中:
k75qkfdt2#
SSL的一些基本知识:
1.什么会触发用户名和密码的URLAuthenticationChallenge。它是HTML中的特定头值吗?
如果你有https连接,这些方法将被触发。这些是出于安全目的,以防止中间人攻击。例如,我可以设置查尔斯代理服务器,安装在模拟器/设备的公共证书,并可以监视所有的请求,该应用程序发送到实际的服务器,从而获得敏感信息(API密钥,令牌,请求头,请求体等),我需要隐藏攻击者。
对于来自服务器的用户名和密码请求,我应该期待哪个URLAuthenticationChallenge protectionSpace。
您可以将服务器证书与应用中的本地证书进行比较:
也可以比较公钥:
比较公钥是一种更好的方法,因为在比较证书时,您必须在应用程序中保留本地证书的副本,当证书到期时,您必须更新应用程序中的证书,这需要在应用程序商店中更新。