LoginSignup
6
7

More than 5 years have passed since last update.

.Net Core で サーバー証明書の検証をスキップする

Last updated at Posted at 2018-02-26

自分に対するメモ。

.NET Core で、REST-API にアクセスしたいときに、サーバー証明書の検証をスキップしたい時がある。その時のコードの書き方。今やりたいのは、Kubernetesの REST API のアクセスを.NET Core からしたい。その時に、Kubernetes は独自の証明書を使っているから普通にはアクセスできません。次のサイトにまとまっています。

本来の方法は、上記のブログにかいてあるとおり、ルート証明書を k8s から取得してコンフィグするのでしょうが、最初のステップとして、SSL証明書をスキップして、ちゃんとREST-API が呼べるかどうかを確認しましょう。

実装

.Net Core での書き方は依然とは異なるようで、基本的には、下記のように書いてあげればOK. つまりコールバックの関数をわたすところで、カスタムのコールバックとして、常にTrueを返すという感じ。

var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPlicyErrors) => true;
client = new HttpClient(httpClientHandler);    

ちなみにソースコードは、Resource のところに、GitHub に置いておきました。

エラーメッセージ

実は、サーバー証明書の検証をスキップするところで結構はまりました。もともと、curlでは、動いていたのですが、C#で実装すると、セキュリティエラー というあいまいなエラーメッセージがでて全然原因がわかりませんでした。結局 curl のほうで、--insecureオプションをつけていたのを忘れたので、気づいたのですが、エラーメッセージからわからないのはつらすぎるので、コントリビュートしてみることを画策中です。

System.Net.Http.HttpRequestException
  HResult=0x80072F8F
  Message=An error occurred while sending the request.
  Source=System.Private.CoreLib
  StackTrace:
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at System.Net.Http.DiagnosticsHandler.<SendAsync>d__2.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at System.Net.Http.HttpClient.<FinishSendAsyncBuffered>d__58.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at KubernetesRestSpike.Program.<RunAsync>d__7.MoveNext() in C:\Users\tsushi\Source\Repos\CustomBindingsSample\KubernetesRestSpike\Program.cs:line 42
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at KubernetesRestSpike.Program.Main(String[] args) in C:\Users\tsushi\Source\Repos\CustomBindingsSample\KubernetesRestSpike\Program.cs:line 31

Inner Exception 1:
WinHttpException: セキュリティ エラーが発生しました

実装はたぶんこの辺り。まだ見つけられていないので、見つけたらおしえてください。
ServerCertificate

と、思ったら元同僚が助けてくれた。やっぱ彼イケメン!ありがとう!
ちなみに、エラーメッセージはどうやら、Windows からとっているようなので、多分Windows のほうがこのメッセージを変えることは望み薄なので、まずはIssue から始めるといいんじゃない?ってアドバイスくれました。

Hi Tsuyoshi,

Looking at the code, it seems that whenever there is a ServerCertificateValidationCallback set and it returns false, a generic WinHttpException is created with an error message from an error message id:

https://github.com/dotnet/corefx/blob/7e6396b2bcb4d372b199cfb7b3b13e290c441124/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestCallback.cs#L312-L313

The message is coming from Windows itself via a call to the Windows API function FormatMessage (https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).aspx) passing in ERROR_WINHTTP_SECURE_FAILURE (12175).

Given Windows is unlikely to change this message, perhaps the CoreFx maintainers would accept a PR to improve the experience.

Your best bet is to file an issue in the dotnet/corefx repo with a full repro.

I hope that helps!

Peter

Issue をポストしておきました。(Resource参照)

今回の反省としては、コードを読めば自分でも理解できる(かも)レベルだったのに、実装のありかにとらわれてエラーメッセージを変更したいという本来のゴールをわすれていたので、探すのに苦労しました。もっと目的にフォーカスしよう。

Resource

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7