NSURLCredentialStorage默认凭据未自动使用

时间:2014-09-10 02:54:24

标签: ios nsurlsession nsurlcredentialstorage

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

根据以下记录的消息,保护空间是相同的(我在设置凭证时创建的保护空间和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 *)挑战委托方法:

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

结果

<NSURLCredential: 0x1680ff00>: thecorrectusername

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

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

编辑: 我已经将手动凭证处理添加到didReceiveChallenge:方法中,并且尽管只使用了一个NSURLSession,但它已针对每个请求进行了触发。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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