簡體   English   中英

Microsoft GraphServiceClient 返回“根據驗證程序遠程證書無效”

[英]Microsoft GraphServiceClient returns "remote certificate is invalid according to the validation procedure"

我注意到 GraphServiceClient 在我的 .net framework 4.6.1 MVC webapp 中連接到 Microsoft Graph API 的奇怪(對我而言)行為。 我使用 System.Net.WebClient 從https://login.microsoftonline.com/common/oauth2/v2.0獲取或刷新訪問令牌,效果很好。

但是,使用 GraphServiceClient 使用 Microsoft 的 Graph API 在某些情況下會失敗,並返回以下異常:

[AuthenticationException: 根據驗證程序,遠程證書無效。]
System.Net.TlsStream.EndWrite(IAsyncResult asyncResult) +300
System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar) +180

[WebException:底層連接已關閉:無法為 SSL/TLS 安全通道建立信任關系。]
...(為簡潔起見,我修剪了其余部分)

我嘗試/檢查的內容:

  • 來自 graph.microsoft.com/ 的證書(Microsoft 的)在我的機器上有效且受信任,並且鏈中似乎不包含其他(代理)證書。
  • 對返回 true 的 ServicePointManager.ServerCertificateValidationCallback 使用回調,總是有效(不再拋出異常),但我不想在我的代碼中使用這個 hack。
  • 從上述 hack 調試 ServerCertificateValidationCallback 時,sslPolicyErrors 參數似乎總是設置為“SslPolicyErrors.none”,那么證書驗證何時會失敗?
  • - 使用 System.Net.WebClient 來使用圖形 API 而不是 GraphServiceClient,只是一直有效。 GraphServiceClient 在證書檢查方面比 System.Net.WebClient 做什么更多? (編輯:我的壞處:webclient 的 ServicePointManager.ServerCertificateValidationCallback 返回 true)
  • 使用 Postman 使用相同的訪問令牌來使用圖形 API 很簡單。
  • 使用 System.Net.WebClient 和之后(見下面的代碼)使用 GraphServiceClient 來獲取相同的數據很簡單,所以我可以讓 GraphServiceClient 工作,只是它必須在使用連接到 API 的其他代碼之前System.Net.WebClient(這實際上是最奇怪的部分)。 (編輯:我的壞處:這是正常的,因為 webclient 有 ServicePointManager.ServerCertificateValidationCallback 返回 true)
  • 在我們的登台環境中,GraphServiceClient 可以正常工作(沒有黑客或前面的 WebClient 代碼),所以我猜這是我的開發 PC 上的某些東西和 GraphServiceClient 的使用的組合。
  • 我的 PC 上確實啟用了 Cisco AMP(但我無法將其關閉)。 我們的網絡中沒有代理服務器。

代碼:

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”hack 時,我在 Fiddler 中看到了這些數據。 讓我擔心的是請求中的“時間”字符串,它似乎是過去的。 該字符串在哪里生成?

請求原始:

連接 graph.microsoft.com:443 HTTP/1.1 主機:graph.microsoft.com

發現了 SSLv3 兼容的 ClientHello 握手。 Fiddler 提取了以下參數。

版本:3.3 (TLS/1.2) 隨機:5E 67 B7 58 60 39 A6 18 3B 07 3C F0 88 17 E4 85 A7 3C 58 76 85 DE F4 0F EF 4C 76 ED DB "Time/5" 2 2017 1:29:18 SessionID: 43 4C 00 00 8C 73 51 69 9E 8B FB 24 8B E2 6B C2 B5 AA 0B E1 45 20 80 F4 98 BE A2 03 Dmicrosoftcomname DF 1s2E 支持的擴展名 DF 59 1s 擴展圖: [0x1d],secp256r1 [0×17],secp384r1 [為0x18] ec_point_formats未壓縮的[為0x0] signature_algs rsa_pkcs1_sha256,rsa_pkcs1_sha384,rsa_pkcs1_sha1,ecdsa_secp256r1_sha256,ecdsa_secp384r1_sha384,ecdsa_sha1,DSA_SHA1,rsa_pkcs1_sha512,ecdsa_secp521r1_sha512 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_E CDSA_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_COMPRESSION

響應原始:

HTTP/1.1 200 連接建立 FiddlerGateway: Direct StartTime: 16:50:48.111 Connection: close

加密的 HTTPS 流量流經此 CONNECT 隧道。 HTTPS 解密在 Fiddler 中啟用,因此在此隧道中運行的解密會話將顯示在 Web 會話列表中。

安全協議:Tls12 密碼:Aes128 128bits 哈希算法:Sha256 ?bits 密鑰交換:ECDHE_RSA (0xae06) 255bits

== 服務器證書 ========== [主題] CN=graph.microsoft.com

[發行者] CN=Microsoft IT TLS CA 2,OU=Microsoft IT,O=Microsoft Corporation,L=Redmond,S=Washington,C=US

【序列號】20000549F729A8A47312D9F3220000000549F7

[不是之前] 27/01/2019 20:09:45

[之后] 27/01/2021 20:09:45

【指紋】2D4A597DE7EA5A28474EEAB141E8A085907A900A

[SubjectAltNames] graph.microsoft.com

找到了。 罪魁禍首是 dropbox API 客戶端,我也在同一個 Web 應用程序中使用它。 特別是這行代碼:

DropboxCertHelper.InitializeCertPinning();

這行代碼還實現了 ServicePointManager.ServerCertificateValidationCallback,並可能使用 HttpClient 或 WebClient 破壞其他代碼。

更多信息https://github.com/dropbox/dropbox-sdk-dotnet/issues/74

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM