Microsoft GraphServiceClient 返回"remote certificate is invalid according to the validation procedure"



我注意到GraphServiceClient在我的.net框架4.6.1 MVC Web应用程序中连接到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的)在我的计算机上是有效和受信任的,并且链中似乎不包含其他(代理)证书
  • 对ServicePointManager.ServerCertificateValidationCallback使用返回true的回调始终有效(不再抛出异常),但我不希望在代码中使用此破解
  • 当调试来自上述破解的ServerCertificateValidationCallback时,sslPolicyErrors参数似乎总是设置为"sslPolicyErrors.none",那么证书验证什么时候失败呢
  • -使用System.Net.WebClient来使用图API而不是GraphServiceClient,始终有效。GraphServiceClient在证书检查方面比System.Net.WebClient做得更多的是什么(编辑:我的错:Web客户端的ServicePointManager.ServerCertificateValidationCallback返回true)
  • 使用Postman使用相同的访问令牌来消费图API就可以了
  • 使用System.Net.WebClient,然后使用GraphServiceClient获取相同的数据(请参阅下面的代码),这样我就可以让GraphService客户端工作,只是它前面必须有使用System.Net.WebClient连接到API的其他代码(这实际上是最奇怪的部分)(编辑:我的错:这很正常,因为Web客户端有ServicePointManager.ServerCertificateValidationCallback返回true)
  • 在我们的暂存环境中,GraphServiceClient可以正常工作(没有黑客或之前的WebClient代码),所以我想这是我的开发PC上的一些东西和GraphServiceClient的使用的结合
  • 我的电脑上确实有活动的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"破解时,我在Fiddler中看到了这些数据。让我担心的是请求中的"时间"字符串,它似乎已经过去了。这个字符串是从哪里生成的?

原始请求:

CONNECT graph.microsoft.com/443 HTTP/1.1主机:graph.microsoft.com

找到了SSLv3兼容的ClientHello握手。小提琴手提取以下参数。

版本:3.3(TLS/1.2)随机:5E 67 B7 58 60 39 A6 18 3B 07 3C F0 8817 E4 85 A7 3C 58 76 85 DE F4 0F EF 4C 76 ED DB 10 52 DE"时间":2017年3月2日1:29:18会话ID:43 4C 00 00 8C 73 51 69 9E 8B FB 24 8B E26B C2 B5 AA 0B E1 45 20 80 F4 98 BE A2 03 DF 1E D8 B3接长件:server_name graph.microsoft.com supported_groups x25519[0x1d],secp256r1[0x17],secp384r1[0x18]ec_point_formats未压缩[0x0]签名_,rsa_ccs1_sha1、ecdsa\usecp256r1_sha256、ecdson\usecp384r1_sha384,ecdsa_sha1、dsa\usha1、rsa_ccs1_sha512、ecdsa\usecp521r1_sha512会话票证为空extended_master_secret为空representation_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[0009d]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:直接启动时间:16:50:48.111连接:关闭

加密的HTTPS流量流经此CONNECT隧道。HTTPSFiddler中启用了解密,因此解密会话在中运行此隧道将显示在"Web会话"列表中。

安全协议:Tls12密码:Aes128 128位哈希算法:Sha256?位密钥交换:ECDHE_RSA(0xae06)255位

===服务器证书======[主题]CN=graph.microsoft.com

[颁发者]CN=Microsoft IT TLS CA 2,OU=Microsoft IT,O=MicrosoftCorporation,L=雷德蒙德,S=华盛顿,C=美国

【序列号】20000549F729A8A47312D9F3220000000549F7

【之前】2019年1月27日20:09:45

【不在此之后】2021年1月27日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

相关内容

最新更新