アプリ開発ときどきアウトドア

主にJavaを使ったアプリ開発やトラブルシューティング等のノウハウ、キャンプや登山の紹介や体験談など。

1. システムエンジニアリング ASP.NET Core 実装技術

ASP.NET Core: IHttpClientFactoryの検証用サンプル

投稿日:2020年4月19日 更新日:

本番環境ではあまり使うことはない、検証環境を想定したサンプルを紹介します。
本来のIHttpClientFactoryの使い方や基本的なサンプルは下記を参考にしていただければと思います。

前提

  • マイクロソフトが推奨するIHttpClientFactoryを使用して、HttpClientクライアントを取得する前提です。
  • サンプルはWindows10 + Visual Studio 2019(ASP.NET Core 3.1)環境で確認しています。

サンプル

サンプルのプロジェクトや完全なソースコードは次で公開しています。

既定のHttpClientのオプション指定方法

既定のHttpClientにオプションを指定するインターフェイスは用意されていません。
名前付きクライアントにオプションを指定するインターフェイスはあるので、既定のクライアントを意味するOptions.DefaultName(“”)を指定して、オプションを指定できます。
業務では名前付きクライアントか型付きクライアントを使用すると思うので、これは検証用のTIPSになると思います。

public void ConfigureServices(IServiceCollection services)
{
...
    services.AddHttpClient(Options.DefaultName, options =>
    {
        options.BaseAddress = new Uri("https://localhost:44399");
        options.DefaultRequestHeaders.Add("X-ACCESS-KEY", "secret");
        options.DefaultRequestHeaders.Accept.Clear();
        options.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
    });
...

サーバ証明書のエラーを無視する方法

通常、サーバ証明書の有効期限やホスト名の検証に失敗すると、次のようにSSLエラーの例外が発生します。

...
System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
 ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
   at System.Net.Security.SslStream.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
...
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Security.SslStream.ThrowIfExceptional()
...

このようなSSLのエラーを無視して通信を行いたい場合、次のようにサーバ証明書の検証ロジックを変更することで実現できます。(この例では、「常に成功」を返す検証ロジックを追加しています。)

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpClient("bypass-ssl-validation")
        .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler{ 
            ServerCertificateCustomValidationCallback = (
                httpRequestMessage, cert, certChain, policyErrors) => {
               return true;
            }
        });

この変更を行うと全てのサーバ証明書の検証が無効になってしまいセキュリティが低下するので、検証や開発環境に限定した使用を推奨します。もし本番環境でSSLエラーの問題を解決したい場合、サーバ証明書を正しいものに更新する、信頼するサーバ証明書として登録する等、別の方法を推奨します。

HttpClientの通信内容のロギング方法

名前付きクライアントの場合ですが、次のようにSystem.Net.Http.HttpClient.{名前}.ClientHandlerのログレベルをTraceに変更することでHTTP要求/応答のHTTPヘッダをログ出力できます。
HTTPボディをログ出力する場合、HttpClientHandlerの実装が必要になります。

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information",

      // HTTP要求/応答のロギング
      "System.Net.Http.HttpClient.Default.ClientHandler": "Trace",
      "System.Net.Http.HttpClient.basic.ClientHandler": "Trace",
      "System.Net.Http.HttpClient.bypass-ssl-validation.ClientHandler": "Trace"
    }
  }
}

ログ出力の例は次の通りです。

System.Net.Http.HttpClient.basic.LogicalHandler: Information: Start processing HTTP request GET https://localhost:44399/api/SampleApi?arg1=abcxyz!%23$%25%26_%3D-003&arg2=あいうえお
System.Net.Http.HttpClient.basic.ClientHandler: Information: Sending HTTP request GET https://localhost:44399/api/SampleApi?arg1=abcxyz!%23$%25%26_%3D-003&arg2=あいうえお
System.Net.Http.HttpClient.basic.ClientHandler: Trace: Request Headers:
X-ACCESS-KEY: secret
Accept: application/json

System.Net.Http.HttpClient.basic.ClientHandler: Information: Received HTTP response after 147.3151ms - OK
System.Net.Http.HttpClient.basic.ClientHandler: Trace: Response Headers:
Transfer-Encoding: chunked
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Sun, 19 Apr 2020 09:59:43 GMT
Content-Type: application/json; charset=utf-8

System.Net.Http.HttpClient.basic.LogicalHandler: Information: End processing HTTP request after 165.0041ms - OK

実際の通信は次のようになっています。
上記ではクエリ文字列の日本語がそのまま出力されていますが、実際には次のようにURLエンコードされています。
また、出力されないヘッダがあることも注意してください。

GET /api/SampleApi?arg1=abcxyz!%23$%25%26_%3D-003&arg2=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A HTTP/1.1
Host: localhost:8080
X-ACCESS-KEY: secret
Accept: application/json
Request-Id: |623d2d43-44...

正確な通信内容を確認したい場合はwiresharkやtcpdump等のパケットキャプチャツールの使用をお薦めします。
HTTP要求/応答をログ出力するDelegatingHandlerを実装することもできますが、上記と同様に取得できないヘッダ情報があったり、勝手にデコードされてたりするので正確ではありません。



(adsbygoogle = window.adsbygoogle || []).push({});


(adsbygoogle = window.adsbygoogle || []).push({});

-1. システムエンジニアリング, ASP.NET Core, 実装技術

執筆者:

関連記事

Hyper-VでリモートのISOイメージをマウント

皆で使用するCD/DVDはISOイメージファイルとして、ファイルサーバ上の共有フォルダに配置する運用を想定しています。Hyper-V上の仮想マシンのCD/DVDドライブに、これらのISOイメージファイ …

Javaによるzipファイルの安全な解凍方法

以前、業務アプリ(Java)でzipファイルの操作が必要となったため、Javaにおけるzip圧縮解凍について調査しました。また、zip4jを使った圧縮・解凍についても説明しました。 ここでは、もう少し …

開発・検証用のダミーメールサーバの構築(fakeSMTP)

アプリ開発や検証等でメールサーバを利用したい場合がある。 プロジェクトで共有の検証用メールサーバを構築できると効率が良いか、その準備が間に合わなかったり、使用者が限定的な場合は、使用者の開発環境上に構 …

技術検証

Linuxでの gdrive の使い方

wordpressのデータをgoogle driveにバックアップするための基礎調査を行っている。 google driveに接続可能なライブラリは幾つかあるようだが、ここでは無料でお手軽に始められそ …

システムエンジニアによる嫌われる勇気の実践

愚直に成果を出すことしか知らなかったシステムエンジニアが、デスマーチなプロジェクトで心を病みそうになったが、「嫌われる勇気」を読んで逆に強くなったお話です。 モノ作りが好きだが「コミュニケーションが苦 …