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

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

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

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

投稿日:

これまでにIHttpClientの使い方やサンプルの説明をしました。
今回は検証用のサンプルを説明します。

前提

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

サンプル

既定のクライアントのオプション指定

既定の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/TLS)のエラーを無視する

通常、サーバ証明書の有効期限やホスト名の検証に失敗すると、次のように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エラーの問題を解決したい場合、サーバ証明書を正しいものに更新する、信頼するサーバ証明書として登録する等、別の方法を推奨します。

HTTP通信内容のロギング

名前付きクライアントの場合ですが、次のように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, 実装技術

執筆者:

関連記事

chromeのjavascriptを一時的に無効化

Webアプリの開発やテストで、クライアント側のバリデーションを無効にしてサーバ側バリデーションの動作確認する、等のように一時的にjavascriptを無効にしたい場合があります。これを実現するための方 …

ftp, ftps, sftpの違い

開発対象システムの連携先システムとして、ftpsやらftpsサーバが指定される場合がある。 私の場合、開発標準の役割を担う場合が多く、これらの仕様を把握し、動作確認や単体テスト用のダミーのサーバを用意 …

疎通確認用pingツール

新人君たちと本番環境の構築作業でデータセンターに入り。 構築したサーバから、既存の重要なサーバへの疎通確認を行うために、pingを何度も入力する予定とのこと。 作業時間の短縮や間違いの低減のために、こ …

ASP.NET Core: 変更ページを実行環境に反映

ASP.Net Core(3.0)の開発で、ページ(cshtml)を編集しながらページデザインを確認したい。 既定ではページを変更しても実行環境に反映れずサーバの再起動が必要となり開発効率が悪い。 サ …

システム開発でのmybatis-generatorの利用

システム開発における製造工程の前段では、開発メンバの負荷軽減や共通化のために、各テーブルに対するSELECT/INSERT/UPDATE/DELETEを容易に行うための共通クラスを準備することが望まれ …

プロフィール ゆっきーです。
都内でシステムエンジニアをやっています。
もっと詳細を見る