我从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,但它已针对每个请求进行了触发。
答案 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