NSURLSession обработчик завершения, означающий, если didReceiveChallenge автоматически вызывается - PullRequest
0 голосов
/ 30 ноября 2018

Может кто-нибудь объяснить мне, если автоматически вызывается didReceiveChallenge после того, как я сделаю запрос на сервер https с NSURLSession, если обработчик завершения вызывает некоторые внутренние методы после завершения didReceiveChallenge и как я могу получить доступ к этому обработчику завершения?метод делегата имеет следующую фирму:

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler

[EDIT]

Обычно я вижу этот метод в этой базовой реализации:

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
{
  if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
  {
    if([challenge.protectionSpace.host
        isEqualToString:@"google.it"])
    {
      NSURLCredential *credential = [NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust];
      completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
    }
    else
      completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
  }

}

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Прежде всего, спасибо за ваше время.Я постараюсь лучше объяснить, каковы мои требования.У меня есть два возможных случая ANY и SYSTEM_VALIDATED, и исходя из этого я должен сделать следующее:

  • ANY: я должен разрешить любые сертификаты
  • SYSTEM_VALIDATED: каркас, который я создаю, читает файл data.bin из клиентского пакета приложения, и этот файл может содержать один или несколько CA (центр сертификации) (CASE A), который компания, которая запросила этот SDK, предоставила нам илион может содержать простое слово «СИСТЕМА» (СЛУЧАЙ B).В этом случае я должен сделать следующие вещи

    • ПРИМЕР A: сравнить сертификат (ы), которые я должен создать из файла data.bin, с открытым ключом сертификата доверия сервера
    • СЛУЧАЙ B: сравнить все сертификаты, установленные в системе, с открытым ключом сертификата доверия сервера

ЛЮБОЙ случай, если я не ошибаюсь, должен быть выполнен следующимдве строки выше:

NSURLCredential *credential = [NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust];
    completionHandler(NSURLSessionAuthChallengeUseCredential,credential);   

CASE A Я должен сделать сравнение вручную и оценить сертификаты, и, возможно, для CASE B я ничего не должен делать и позволить Системе загрузки URL по умолчанию оценить доверие сервера

Я сейчас читаю эту яблочную документацию и эту яблочную документацию .Я понимаю, что мне следует доверить оценку сервера вручную для CASE A, но для CASE B и ЛЮБОГО я должен вызывать эти две строки выше или ничего не делать и позволить системе загрузки URL обрабатывать все?

[EDIT]

Я забыл упомянуть, что этот запрос отправлен серверной компании, которая поддерживает TLS 1.2 с действующим сертификатом CA.

0 голосов
/ 30 ноября 2018

Прежде чем идти дальше, я должен начать с указания, что делать что-либо из этого - почти всегда ошибка .Вы можете получить бесплатные сертификаты TLS от различных групп, таких как LetsEncrypt .Поэтому, если у вас нет очень необычного варианта использования (например, необходимо обеспечить доверие для устройств, которые не подключены к общедоступному Интернету, общаться через локальную сеть связи), вам почти всегда лучше , а не делать какие-либооб этом, и просто установить настоящий сертификат TLS на тестовом сервере.

С учетом сказанного ....

Метод URLSession:didReceiveChallenge:completionHandler: вызывается на делегате сеанса (если не ноль) всякий раз, когда ОС требуется запросить дополнительное подтверждение.Это может быть вызвано не для каждого запроса, но обычно так и есть.Он вызывается для каждого https-запроса, точка из-за оценки доверия к серверу.

Возможно, приведенный выше код не работает, потому что вы не запрашиваете обработку по умолчанию в тех случаях, когда пространство защиты отличается отдоверие к серверу (например, проверка подлинности прокси-сервера, базовая HTTP-аутентификация / аутентификация дайджеста и т. д.), что означает, что сетевой механизм просто сидит и ждет, когда вы скажете ему, что делать, не обращая внимания на тот факт, что переданный им блок был освобожден, когдаметод возвращен и, следовательно, никогда не будет вызван.

Вы должны делать что-то вроде этого:

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
{
  if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
  {
    if([challenge.protectionSpace.host isEqualToString:@"google.it"])
    {
      if (/* Manually verify the certificate here in some way */) {
        NSURLCredential *credential = [NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust];
        completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
      } else {
        // Evaluation failed.  Reject the certificate.
        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
      }
      // Do not fall through for either case above.
      return;
    }
  }
  completionHandler(NSURLSes NSURLSessionAuthChallengePerformDefaultHandling, nil);
}

Кроме того, код, который вы разместили, очень небезопасен, потому что вы ничего не делаете дляподтвердить сертификат.См. Корректная проверка правильности цепочки TLS в документации для разработчиков Apple для получения дополнительной информации о том, как сделать этот шаг, но обычно вы делаете это либо с помощью

  • Предоставляя копию корневого сертификата (без ключа) используется для подписи вашего поддельного сертификата, затем добавление этого корневого сертификата к набору действительных корневых сертификатов, затем повторная оценка сертификата.
  • Предоставление копии открытого ключа для поддельного сертификата и утверждение, чтоон соответствует ожидаемому ключу.

При любом подходе вам, вероятно, следует вернуться к обработке по умолчанию, так что если вы когда-нибудь замените самозаверяющий сертификат реальным, он будет "просто работать".

...