Microsoft GraphServiceClient возвращает «удаленный сертификат недействителен в соответствии с процедурой проверки» - PullRequest
0 голосов
/ 10 марта 2020

Я замечаю странное (для меня) поведение GraphServiceClient для подключения к Microsoft Graph API в моем. net framework 4.6.1 MVC webapp. Я использую System. Net .WebClient, чтобы получить или обновить sh токен доступа от https://login.microsoftonline.com/common/oauth2/v2.0, и это прекрасно работает.

Однако использование API-интерфейса Graph Microsoft с использованием GraphServiceClient в некоторых случаях возникает ошибка, возвращая это исключение:

[AuthenticationException: удаленный сертификат недействителен в соответствии с процедурой проверки.]
System. Net .TlsStream.EndWrite (IAsyncResult asyncResult) + 300
System. Net .ConnectStream.WriteHeadersCallback (IAsyncResult ar) + 180

[WebException: базовое соединение было закрыто: не удалось установить sh доверительные отношения для безопасного канала SSL / TLS .]
... (я сократил остальное для краткости)

Что я пробовал / проверял:

  • Сертификат (Microsoft) от graph.microsoft. com / является допустимым и доверенным на моем компьютере и, по-видимому, не содержит других (прокси) сертификатов в цепочке.
  • Использование обратного вызова для ServicePointManager.ServerCertificate ValidationCallback, который возвращает true, всегда работает (исключение больше не генерируется), но я предпочитаю не использовать этот хак в моем коде.
  • При отладке ServerCertificateValidationCallback из вышеприведенного хака параметр sslPolicyErrors всегда кажется установленным в «SslPolicyErrors.none», поэтому, когда проверка сертификата все равно не выполняется?
  • - Использование System. Net .WebClient для использования API-интерфейса графика вместо GraphServiceClient просто работает все время. Что делает GraphServiceClient с точки зрения проверки сертификатов больше, чем система. Net .WebClient? (РЕДАКТИРОВАТЬ: Мой плохой: у веб-клиента ServicePointManager.ServerCertificateValidationCallback возвращают true)
  • Использование Postman для потребления Графический API, использующий тот же токен доступа, просто работает.
  • Использование системы. Net .WebClient, а затем (см. код ниже) с помощью GraphServiceClient для получения тех же данных просто работает, поэтому я МОГУ заставить GraphServiceClient работать, только ему должен предшествовать другой код, который подключается к API с помощью системы. Net .WebClient (на самом деле это самая странная часть). (РЕДАКТИРОВАТЬ: Мое плохо: это было нормально поскольку у веб-клиента ServicePointManager.ServerCertificateValidationCallback возвращает true)
  • В нашей промежуточной среде GraphServiceClient работает так, как и должно (без взломов или предшествующего кода WebClient), поэтому я полагаю, что это сочетание чего-то в моем dev P C и использование GraphServiceClie Нет.
  • У меня активирован Cisco AMP на моем P C (но я не могу его выключить). В нашей сети нет прокси-сервера.

Код:

private static GraphServiceClient GetGraphClient(string accessToken) {
    return new GraphServiceClient(new DelegateAuthenticationProvider((requestMessage) => {
        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
        return Task.FromResult(0);
    }));
}

async public static Task<List<Appointment>> GetAppointments(string accessToken, int eventsAmountToGet) {
    List<QueryOption> queryOptions = new List<QueryOption>(){
        new QueryOption("startDateTime", DateTime.UtcNow.ToString("o")),
        new QueryOption("endDateTime",  DateTime.UtcNow.AddDays(30).ToString("o"))
    };

    GraphServiceClient graphClient = GetGraphClient(accessToken);
    //the following line will fail (remote certificate ...) 
    IUserCalendarViewCollectionPage result = await graphClient.Me.CalendarView.Request(queryOptions).GetAsync();
    return result.Select(x => new Appointment {
        Subject = x.Subject.ToString(),
        Start = x.Start.ToDateTime(),
        End = x.End.ToDateTime(),
        Organiser = x.Organizer.EmailAddress.Name
    }).Take(eventsAmountToGet).ToList();
}

Редактировать: При использовании хака "ServicePointManager.ServerCertificateValidationCallback return true" я вижу эти данные в Fiddler. Что меня беспокоит, так это строка "time" в запросе, которая, похоже, в прошлом. Где генерируется эта строка?

Необработанный запрос:

CONNECT graph.microsoft.com:443 HTTP / 1.1 Хост: graph.microsoft.com

A SSLv3-совместимое клиентское приветствие было найдено. Fiddler извлек параметры ниже.

Версия: 3.3 (TLS / 1.2) Случайная: 5E 67 B7 58 60 39 A6 18 3B 07 3 C F0 88 17 E4 85 A7 3 C 58 76 85 DE F4 0F EF 4 C 76 ED DB 10 52 DE «Время»: 02.03.2017 1: 29: 18 SessionID: 43 4 C 00 00 8 C 73 51 69 9E 8B FB 24 8B E2 6B C2 B5 AA 0B E1 45 20 80 F4 98 BE A2 03 DF 1E D8 B3 Расширения: имя сервера ] signature_algs rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_sha1, dsa_sha1ss1s5s5_5_1_5_5_5_5_1_5_5_5_1_5_1_5_1_5_1_5_1_5_1_5_1_5_5_1_5_1_5_5 SessionTicket пустых extended_master_secret опорожнить renegotiation_info 00 шифры: [C02C] TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 [C02B] TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 [C030] TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 [C02F] TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [009F] TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 [009E] TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 [C024] TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 [C023] TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 [C028] TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 [C027] TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 [C00A ] TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA [C009] TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA [C014] TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA [] C013 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA [009D] TLS_RSA_WITH_AES_256_GCM_SHA384 [009C] TLS_RSA_WITH_AES_128_GCM_SHA256 [003D] TLS_RSA_WITH_AES_256_CBC_SHA256 [003C] TLS_RSA_WITH_AES_128_CBC_SHA256 [0035] TLS_RSA_WITH_AES_256_CBC_SHA [002F] TLS_RSA_WITH_AES_128_CBC_SHA [000A] SSL_RSA_WITH_3DES_EDE_SHA

Сжатие: [00] NO_ СЖАТИЕ

Необработанный ответ:

HTTP / 1.1 200 Установлено соединение FiddlerGateway: Direct StartTime: 16: 50: 48.111 Соединение: закрыто

Зашифрованный трафик HTTPS c проходит через этот туннель CONNECT. Расшифровка HTTPS включена в Fiddler, поэтому расшифрованные сеансы, запущенные в этом туннеле, будут показаны в списке веб-сеансов.

Безопасный протокол: Tls12 Шифр: Aes128 128 битов Ha sh Алгоритм: Sha256? Бит Обмен ключами: ECDHE_RSA (0xae06) 255bit

== Сертификат сервера ========== [Тема] CN = graph.microsoft.com

[Эмитент] CN = Microsoft IT TLS CA 2 , OU = Microsoft IT, O = Microsoft Corporation, L = Редмонд, S = Вашингтон, C = США

[Серийный номер] 20000549F729A8A47312D9F3220000000549F7

[Не раньше] 27/01/2019 20: 09: 45

[не после] 27/01/2021 20: 09: 45

[отпечаток] 2D4A597DE7EA5A28474EEAB141E8A085907A900A

[SubjectAltNames] graph.microsoft.com

1 Ответ

0 голосов
/ 11 марта 2020

Нашел это. Виновником был клиент API Dropbox, который я также использую в том же веб-приложении. В частности, эта строка кода:

DropboxCertHelper.InitializeCertPinning();

Эта строка кода также реализует ServicePointManager.ServerCertificateValidationCallback и, возможно, нарушает другой код с помощью HttpClient или WebClient.

Подробнее https://github.com/dropbox/dropbox-sdk-dotnet/issues/74

...