1

我正在从 NSURLConnection 切换到 NSURLSession 以进行我的应用程序通信,并且在我使用它的同时,尝试从委托身份验证转移到使用 NSURLCredentialStorage。我已经移动了代码,但是尽管在应用程序启动时在 sharedCredentialStorage 上设置了 defaultCredentials,但我还是在委托上调用了 -URLSession:task:didReceiveChallenge。

根据以下记录的消息,保护空间是相同的(我在设置凭据时创建的和通过 NSURLAuthenticationChallenge 传递的):

Register credentials for: <NSURLProtectionSpace: 0x162227c0>: Host:192.168.1.99, Server:https, Auth-Scheme:NSURLAuthenticationMethodDefault, Realm:192.168.1.99, Port:23650, Proxy:NO, Proxy-Type:(null)
Unexpected authentication challenge: <NSURLProtectionSpace: 0x1680ee40>: Host:192.168.1.99, Server:https, Auth-Scheme:NSURLAuthenticationMethodDefault, Realm:192.168.1.99, Port:23650, Proxy:NO, Proxy-Type:(null)

在 didReceiveChallenge:(NSURLAuthenticationChallenge*)challenge 委托方法期间:

po [[NSURLCredentialStorage sharedCredentialStorage] defaultCredentialForProtectionSpace:[challenge protectionSpace]]

结果是

<NSURLCredential: 0x1680ff00>: thecorrectusername

https://stackoverflow.com/a/501869/563905表明,当服务器响应 401 质询时,NSURLConnection(这是 NSURLSession 问题吗?)首先检查标头是否有授权(没有任何设置)和然后咨询 NSURLCredentialStorage 以获取保护空间的凭据。

我只是不明白为什么要调用 didReceiveChallenge 代表?当我没有设置委托方法时, NSURLSession 只是重新发送请求而没有任何凭据......我很难过......

编辑:我在 didReceiveChallenge: 方法中添加了手动凭据处理,尽管只使用了一个 NSURLSession,但它会为每个请求触发。

4

2 回答 2

2

我只是遇到了同样的问题,我的 URLSession 不会使用存储的凭据。然后我阅读了 NSURLSession 的参考文档。基本上它所说的是,如果您正在实现自定义委托,那么当调用委托方法时,您必须自己处理所有事情。换句话说,保存凭据是成功的一半。每次服务器需要身份验证时,您都会收到质询,因此在 didReceiveChallenge 方法中,您现在必须手动提取要使用的凭据并将它们传递给完成处理程序。让我知道这是否有意义。

于 2014-11-07T17:10:53.120 回答
0

你需要使用 NSURLSessionTaskDelegate 或 NSURLSessionDelegate。

//这是基本凭据 https://developer.apple.com/documentation/foundation/nsurlsessiontaskdelegate/1411595-urlsession

或者

//这是针对会话级别的挑战——NSURLAuthenticationMethodNTLM、NSURLAuthenticationMethodNegotiate、NSURLAuthenticationMethodClientCertificate 或 NSURLAuthenticationMethodServerTrust https://developer.apple.com/documentation/foundation/nsurlsessiondelegate/1409308-urlsession

例如:

@interface MySessionClass : URLSession <URLSessionTaskDelegate>

@end

@implementation MySessionClass

#pragma mark - Delegate

//That method will call one time if you use NSURLCredentialPersistencePermanent but if you use other type that method it will call all the time.
- (void) URLSession:(NSURLSession *)session 
               task:(NSURLSessionTask *)task 
 didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge 
  completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {

if (challenge.previousFailureCount == 0) {
        NSURLCredential *credential = [NSURLCredential credentialWithUser:self.user password:self.password persistence:NSURLCredentialPersistencePermanent];
        completionHandler(NSURLSessionAuthChallengeUseCredential, credentials);
    } else {
        completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
    }
}

@end
于 2018-05-10T07:21:56.580 回答