web-dev-qa-db-ja.com

特定のルートまたはコントローラーに対してのみSSLクライアント証明書を要求する

Kestrelをサーバーとして使用するASP.NET MVCコアプロジェクトがあります。ユーザーコンテンツ(asp.net mvc)を提供し、エージェント(ソフトウェア)が通信するWeb APIコントローラーをホストします。 HTTPSとクライアント証明書のサポートを有効にしました。問題は、Web APIを呼び出すエージェント(ソフトウェア)にクライアント証明書を要求したいが、通常のブラウザーベースのユーザーにはクライアント証明書を要求/プロンプトしたくないということです。

次の方法でHTTPS /クライアント証明書サポートを有効にしました。

var Host = new WebHostBuilder()
.UseKestrel(options =>
{
    HttpsConnectionFilterOptions httpsoptions = new    HttpsConnectionFilterOptions();
    httpsoptions.ServerCertificate = CertUtil.GetServerCert();
    httpsoptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    httpsoptions.CheckCertificateRevocation = false;

    options.UseHttps(httpsoptions);
})
.UseUrls("http://0.0.0.0:5000", "https://0.0.0.0:5001")
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();
Host.Run();

クライアント証明書のカスタム検証を処理するために、Startup.csに別のミドルウェアハンドラーセットアップがあります。このコードは正常に実行され、その意味ですべてが正常に機能します。

問題はこれがグローバルに発生することであり、私は特定のコントローラーやルートにクライアント証明書を適用することだけを探しています。または、実際には、この時点で任意の粒度を使用します。

基本的に同じ種類の動作を作成しようとすると、IIS)で2つの仮想ディレクトリを作成してから、SSL設定を一方を受け入れ、もう一方を無視するように設定できます。受け入れを指定すると、証明書のブラウザと無視のあるブラウザではできません。

HttpsConnectionFilterOptionsを設定してServerCertificateのみを指定してみましたが、クライアント証明書関連のオプションを設定しないと、クライアント証明書が送信されても​​ブラウザにプロンプ​​トが表示されない場合、サーバーはクライアント証明書を受信できます。ミドルウェアのクライアント証明書ハンドラーがこの関数を呼び出すときにクライアント証明書を表示しないため、これは機能していないようです(ClientCertificateModeがAllowCertificateに設定されている場合に発生します)。

context.Connection.GetClientCertificateAsync();

要するに、Kestrelホスティングでは、より詳細なクライアント証明書のマッピング/処理が可能ですか、それともIISを使用した場合にのみ可能ですか? IISはこのプロジェクトのオプションではないので、クライアント証明書のAPIの側面のためだけに別のプロジェクト/プロセスを作成する必要がない方がいいと思います。助けてくれてありがとう!

10
Paul W.

私はあなたとまったく同じ要件で、同じことをしようとしています。

それは不可能だという結論に達しました。私の回避策は2WebHostBuilderオブジェクトを使用することです-クライアント証明書を必要としない場所のためのものするそれらのための1つ。これには、各IWebHostが異なるポートでリッスンする必要があるという欠点がありますが、あなたが説明するシナリオから、それは大きな問題ではないと思います。

私は同じプロセス内でこれを行うので、このソリューションはその要件に適合します。

4
Cocowalla

context.Connection.GetClientCertificateAsync();でも同じ問題があり、常にnullを返していました。その後、私はKestrelをIIS Expressを通じて常に実行していることに気付きました。

Visual Studioで、デバッガーツールバーからIIS Expressをプロジェクトに変更しました。Kestrelはコンソールアプリケーションとして起動され、クライアント証明書を取得できました。

enter image description here

IIS Expressはクライアント証明書をサポートしていないため、証明書は常に無視されていました。

質問の他の部分については、 Kestrelは、HttpsConnectionFilterOptionsを使用する場合にそのまま使用できるこの粒度をサポートしていないと思います。 Kestrel接続フィルターオプションのソースコード から、クライアント証明書がnullの場合、接続はドロップされます。 HttpsConnectionFilterOptionsのソースコードを変更して、そこから独自のフィルターを作成することができます。次に、ClientCertificateValidationプロパティを使用して、クライアント証明書が送信されない場合に接続を許可するカスタム証明書検証メソッドを指定できます。

お役に立てれば。

3
The Tech Geek

一部のルートにのみクライアント証明書を設定する方法を理解しましたが、Azure Web Appで実行すると、クライアント証明書がコードに渡されません。 IIS Expressで実行している場合も同じ問題です。

この例では、1つのコントローラーに証明書は不要で、他の2つには異なる証明書が必要です。 https://github.com/xavierjohn/ClientCertificateMiddleware

IIS Expressで実行されているnotの場合、証明書はパススルーされます。

1
Xavier John