我正在尝试使用URLSessionDelegateURLCredentials实现基本身份验证

func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void)

苹果建议不要手动编写Authorization标题。所以我试图使用URLCredentials
我在斯威夫特游乐场做了一个很简单的例子:
class Callback: NSObject {}

extension Callback: URLSessionDelegate {
    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) {
        print("received challenge")
        print(challenge.protectionSpace.authenticationMethod)
        completionHandler(.performDefaultHandling, nil)
    }
}

let callback = Callback()
var configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: callback, delegateQueue: nil)

let string = "http://demo0230490.mockable.io/test"
var request = URLRequest(url: URL(string: string)!)
session.dataTask(with: request) { (data, response, error) in
    print("response")
    print(response)
}.resume()

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

问题是-我没有收到授权挑战。
如果您转到浏览器中的http://demo0230490.mockable.io/test,您将看到浏览器显示基本身份验证警报。
从我的模拟http返回头如下:
"Www-Authenticate" =     (
        "Basic realm=\"Access to MRM\""
    );

我还尝试切换到https(我的意思是https://demo0230490.mockable.io/test)来检查我是否会收到NSURLAuthenticationMethodServerTrust类型的身份验证挑战。
这很管用。这意味着我的delegate设置正确,在某些情况下可以工作。
所以问题是:
是否有人可以指出问题或使用URLCredentials(例如使用https://www.mockable.io)为basic auth提供工作示例?

最佳答案

根据documentationurlSession(_:didReceive:completionHandler:)只在两种情况下调用:
当远程服务器要求客户端证书或Windows NT LAN Manager(NTLM)身份验证时,允许您的应用提供
适当的凭据
当会话首次建立到使用SSL或TLS的远程服务器的连接时,允许您的应用验证服务器的
证书链
当您切换到https时,满足第二个条件,因此调用方法。
有两种类型的身份验证挑战:会话级和非会话级。
对于非会话级别的挑战,URLSession调用urlSession(_:task:didReceive:completionHandler:)。对于会话级的挑战,URLSession调用urlSession(_:didReceive:completionHandler:)
会话级挑战和非会话级挑战之间的区别在urlSession(_:task:didReceive:completionHandler:)documentation的讨论部分进行了描述:
对于会话级别的挑战NSURLAuthenticationMethodNTLM,NSURLAuthenticationMethodNegotiate,
NSURLAuthenticationMethodClientCertificate,或
nsurlAuthenticationMethodServer信任NSURLSession对象调用
会话委托的urlSession(:didReceive:completionHandler:)方法。
如果应用程序未提供会话委托方法,则
NSURLSession对象调用任务委托的
urlSession(:task:didReceive:completionHandler:)方法来处理
挑战。
对于非会话级别的挑战(所有其他挑战),URLSession对象调用会话委托的
urlSession(:task:didReceive:completionHandler:)方法来处理
挑战。如果你的应用程序提供会话委托,而你需要
处理身份验证,则必须处理身份验证
在任务级或提供一个任务级处理程序来调用
每个会话处理程序显式。会话代表的
未为调用urlSession(:didReceive:completionHandler:)方法
非会话级挑战。
在您的情况下,应该实现非会话级的质询处理程序:

extension Callback: URLSessionTaskDelegate {
    func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        print("received task challenge")
    }
}

还有一个关于Apple-forum的工作示例。

关于ios - 无法在URLSessionDelegate中接收NSURLAuthenticationMethodHTTPBasic,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51309486/

10-11 19:23