Учетные данные по умолчанию NSURLCredentialStorage не используются автоматически

Я переключаюсь с NSURLConnection на NSURLSession для связи моего приложения и пока пытаюсь перейти от делегированной аутентификации к использованию NSURLCredentialStorage. Я перебрал код, однако получаю -URLSession:task:didReceiveChallenge, вызываемый делегатом, несмотря на то, что при запуске приложения он установил defaultCredentials в sharedCredentialStorage.

Защитные пространства идентичны (тот, который я создал при настройке учетных данных, и те, которые были переданы 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

/questions/11648009/mogu-li-ya-ispolzovat-nsurlcredentialstorage-dlya-bazovoj-autentifikatsii-http/11648024#11648024 указывает, что, когда сервер отвечает на вызов 401, NSURLConnection (это проблема NSURLSession?) сначала проверяет заголовки для Авторизации (там нет никакого набора) и тогда консультируется с NSURLCredentialStorage для учетных данных для пространства защиты.

Я просто не понимаю, почему у меня вызывается делегат didReceiveChallenge? Когда у меня нет установленного метода делегата, NSURLSession просто повторно отправляет запрос без каких-либо учетных данных... Я в тупике...

Редактировать: я добавил ручную обработку учетных данных в метод didReceiveChallenge: и он запускается для каждого запроса, несмотря на то, что используется только один NSURLSession.

2 ответа

Решение

У меня просто была та же проблема, когда мой URLSession не использовал сохраненные учетные данные. Затем я прочитал справочные документы для NSURLSession. По сути, это говорит о том, что если вы реализуете пользовательский делегат, то вам придется обрабатывать все сами, когда вызываются методы делегата. Другими словами, сохранение учетных данных - полдела. Вы будете получать вызов каждый раз, когда серверу требуется аутентификация, поэтому в методе didReceiveChallenge теперь вам нужно вручную извлечь учетные данные для использования и передать их обработчику завершения. Дайте мне знать, если это имеет смысл.

Вам необходимо использовать 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
Другие вопросы по тегам