System.Netおよび関連する名前空間のHttpWebRequest、HttpListener、SmtpClient、SslStream、NegotiateStream、および関連するクラスによって統合 Windows 認証がどのように処理されるかに影響する機能強化が行われました。 セキュリティを強化するための拡張保護のサポートが追加されました。
これらの変更は、これらのクラスを使用して Web 要求を行い、統合 Windows 認証が使用される応答を受信するアプリケーションに影響を与える可能性があります。 この変更は、統合 Windows 認証を使用するように構成されている Web サーバーとクライアント アプリケーションにも影響を与える可能性があります。
これらの変更は、これらのクラスを使用して他の種類の要求を行い、統合 Windows 認証が使用される場合に応答を受信するアプリケーションにも影響を与える可能性があります。
拡張保護をサポートするための変更は、Windows 7 および Windows Server 2008 R2 上のアプリケーションでのみ使用できます。 拡張保護機能は、以前のバージョンの Windows では使用できません。
概要
統合 Windows 認証の設計により、一部の資格情報チャレンジ応答をユニバーサルにできます。つまり、再利用または転送できます。 チャレンジ応答は、少なくともターゲット固有の情報と、できればチャネル固有の情報を使用して構築する必要があります。 その後、サービスは拡張保護を提供して、資格情報チャレンジ応答にサービス プリンシパル名 (SPN) などのサービス固有の情報が確実に含まれるようにすることができます。 資格情報交換でこの情報を使用すると、サービスは、不適切に使用された可能性のある資格情報チャレンジ応答の悪意のある使用からより適切に保護できます。
拡張保護設計は、認証リレー攻撃を軽減するように設計された認証プロトコルの機能強化です。 チャネルとサービスのバインド情報の概念を中心に説明します。
全体的な目的は次のとおりです。
拡張保護をサポートするようにクライアントが更新された場合、アプリケーションは、サポートされているすべての認証プロトコルにチャネル バインディングとサービス バインド情報を提供する必要があります。 チャネル バインド情報は、バインドするチャネル (TLS) がある場合にのみ指定できます。 サービス バインディング情報は常に指定する必要があります。
適切に構成されている更新されたサーバーは、クライアント認証トークンにチャネルとサービス バインド情報が存在する場合に確認し、チャネル バインドが一致しない場合は認証の試行を拒否できます。 展開シナリオによっては、サーバーはチャネル バインド、サービス バインド、またはその両方を検証できます。
更新されたサーバーには、ポリシーに基づくチャネル バインディング情報を含まない下位レベルのクライアント要求を受け入れるか拒否する機能があります。
拡張保護によって使用される情報は、次の 2 つの部分のいずれかまたは両方で構成されます。
チャネル バインド トークンまたは CBT。
サービス プリンシパル名または SPN の形式のサービス バインド情報。
サービス バインディング情報は、特定のサービス エンドポイントに対して認証を行うクライアントの意図を示します。 これは、次のプロパティを使用してクライアントからサーバーに通信されます。
SPN 値は、クリア テキスト形式でクライアント認証を実行するサーバーで使用できる必要があります。
SPN の値はパブリックです。
中間者攻撃がその値を挿入、削除、または変更できないように、SPN は転送中に暗号で保護する必要があります。
CBT は、外部のセキュリティで保護されたチャネル (TLS など) のプロパティであり、内部のクライアント認証チャネルを介してメッセージ交換に結び付ける (バインドする) ために使用されます。 CBT には、次のプロパティが必要です (IETF RFC 5056 でも定義されています)。
外部チャネルが存在する場合、CBT の値は、外部チャネルまたはサーバー エンドポイントを識別するプロパティである必要があります。これは、会話のクライアント側とサーバー側の両方によって個別に到着します。
クライアントによって送信される CBT の値は、攻撃者が影響を受ける可能性のあるものではありません。
CBT 値の秘密については保証されません。 ただし、CBT を保持するプロトコルが暗号化している可能性があるため、サービス バインディングの値とチャネル バインド情報は、認証を実行しているサーバー以外の任意のサーバーによって常に調べることができるという意味ではありません。
CBT は、攻撃者がその値を挿入、削除、または変更できないように、転送中に暗号化整合性を保護する必要があります。
チャネル バインディングは、クライアントが SPN と CBT を改ざん防止の方法でサーバーに転送することによって実現されます。 サーバーは、そのポリシーに従ってチャネル バインディング情報を検証し、それ自体が意図したターゲットであるとは思わない認証の試行を拒否します。 これにより、2 つのチャネルが暗号化によってバインドされます。
既存のクライアントとアプリケーションとの互換性を維持するために、拡張保護をまだサポートしていないクライアントによる認証試行を許可するようにサーバーを構成できます。 これは、"完全に強化された" 構成とは対照的に、"部分的に強化された" 構成と呼ばれます。
System.NetおよびSystem.Net.Security名前空間内の複数のコンポーネントは、呼び出し元のアプリケーションに代わって統合 Windows 認証を実行します。 このセクションでは、統合 Windows 認証の使用に拡張保護を追加するために、System.Net コンポーネントに対する変更について説明します。
拡張保護は現在、Windows 7 でサポートされています。 オペレーティング システムが拡張保護をサポートしているかどうかをアプリケーションが判断できるように、メカニズムが用意されています。
拡張保護のサポートに関する変更
統合 Windows 認証で使用される認証プロセスには、使用される認証プロトコルに応じて、多くの場合、移行先コンピューターによって発行され、クライアント コンピューターに送り返されるチャレンジが含まれます。 拡張保護により、この認証プロセスに新しい機能が追加される
System.Security.Authentication.ExtendedProtection名前空間は、アプリケーションの拡張保護を使用した認証のサポートを提供します。 この名前空間の ChannelBinding クラスは、チャネル バインドを表します。 この名前空間の ExtendedProtectionPolicy クラスは、サーバーが受信クライアント接続を検証するために使用する拡張保護ポリシーを表します。 その他のクラス メンバーは、拡張保護と共に使用されます。
サーバー アプリケーションの場合、これらのクラスには次のものが含まれます。
次の要素を持つ ExtendedProtectionPolicy 。
オペレーティング システムが拡張保護による統合 Windows 認証をサポートしているかどうかを示す OSSupportsExtendedProtection プロパティ。
拡張保護ポリシーを適用するタイミングを示す PolicyEnforcement 値。
デプロイ シナリオを示す ProtectionScenario 値。 これは、拡張保護のチェック方法に影響します。
認証の目的のターゲットとしてクライアントによって提供される SPN との照合に使用されるカスタム SPN リストを含む省略可能な ServiceNameCollection 。
検証に使用するカスタム チャネル バインドを含む省略可能な ChannelBinding 。 このシナリオは一般的なケースではありません
System.Security.Authentication.ExtendedProtection.Configuration名前空間は、アプリケーションの拡張保護を使用した認証の構成をサポートします。
既存の System.Net 名前空間での拡張保護をサポートするために、多くの機能変更が行われました。 これらの変更には、次のようなものがあります。
トランスポート コンテキストを表すSystem.Net名前空間に追加された新しいTransportContext クラス。
クライアント アプリケーションの拡張保護をサポートするためにTransportContextを取得できるようにする、HttpWebRequest クラスの新しいEndGetRequestStreamおよびGetRequestStreamオーバーロード メソッド。
サーバー アプリケーションをサポートするための HttpListener クラスと HttpListenerRequest クラスへの追加。
既存の System.Net.Mail 名前空間内の SMTP クライアント アプリケーションの拡張保護をサポートするために、機能が変更されました。
- SMTP クライアント アプリケーションの拡張保護を使用するときに認証に使用する SPN を表す、SmtpClient クラスのTargetName プロパティ。
既存の System.Net.Security 名前空間での拡張保護をサポートするために、多くの機能変更が行われました。 これらの変更には、次のようなものがあります。
CBT を渡してクライアント アプリケーションの拡張保護をサポートできるようにする、NegotiateStream クラスの新しいBeginAuthenticateAsClientおよびAuthenticateAsClientオーバーロード メソッド。
サーバー アプリケーションの拡張保護をサポートするためにExtendedProtectionPolicyを渡すことができる、NegotiateStream クラスの新しいBeginAuthenticateAsServerおよびAuthenticateAsServerオーバーロード メソッド。
クライアントおよびサーバー アプリケーションの拡張保護をサポートする、SslStream クラスの新しいTransportContext プロパティ。
System.Net.Security名前空間の SMTP クライアントの拡張保護の構成をサポートするために、SmtpNetworkElement プロパティが追加されました。
クライアント アプリケーションの拡張保護
ほとんどのクライアント アプリケーションに対する拡張保護のサポートは自動的に行われます。 HttpWebRequestクラスとSmtpClient クラスでは、基になるバージョンの Windows で拡張保護がサポートされるたびに、拡張保護がサポートされます。 HttpWebRequest インスタンスは、Uriから構築された SPN を送信します。 既定では、 SmtpClient インスタンスは、SMTP メール サーバーのホスト名から構築された SPN を送信します。
カスタム認証の場合、クライアント アプリケーションは、GetChannelBinding メソッドを使用してTransportContextと CBT を取得できるHttpWebRequest クラスのHttpWebRequest.EndGetRequestStream(IAsyncResult, TransportContext)またはHttpWebRequest.GetRequestStream(TransportContext)メソッドを使用できます。
HttpWebRequest インスタンスから特定のサービスに送信される統合 Windows 認証に使用する SPN は、CustomTargetNameDictionary プロパティを設定することでオーバーライドできます。
TargetName プロパティを使用して、SMTP 接続の統合 Windows 認証に使用するカスタム SPN を設定できます。
サーバー アプリケーションの拡張保護
HttpListener は、HTTP 認証を実行するときにサービス バインドを検証するためのメカニズムを自動的に提供します。
最も安全なシナリオは、 HTTPS://
プレフィックスの拡張保護を有効にすることです。 この場合は、PolicyEnforcementを WhenSupported または Always に設定したExtendedProtectionPolicyにHttpListener.ExtendedProtectionPolicyを設定し、ProtectionScenarioTransportSelected A の値に設定WhenSupported、HttpListenerを部分的に書き込むモードに設定します。一方、Alwaysは完全に強化されたモードに対応します。
この構成では、外部のセキュリティで保護されたチャネルを介してサーバーに要求が行われると、外部チャネルに対してチャネル バインドのクエリが実行されます。 このチャネル バインドは認証 SSPI 呼び出しに渡され、認証 BLOB のチャネル バインドが一致することを検証します。 次の 3 つの結果が考えられます。
サーバーの基になるオペレーティング システムは、拡張保護をサポートしていません。 要求はアプリケーションに公開されず、承認されていない (401) 応答がクライアントに返されます。 エラーの理由を示すメッセージが HttpListener トレース ソースに記録されます。
SSPI 呼び出しは、クライアントが外部チャネルから取得した予期された値と一致しないチャネル バインディングを指定したか、サーバー上の拡張保護ポリシーが Always用に構成されているときに、クライアントがチャネル バインディングを提供できなかったことを示す失敗します。 どちらの場合も、要求はアプリケーションに公開されず、承認されていない (401) 応答がクライアントに返されます。 エラーの理由を示すメッセージが HttpListener トレース ソースに記録されます。
サーバー上の拡張保護ポリシーが構成されているため、クライアントは正しいチャネル バインドを指定するか、チャネル バインドを指定せずに接続を許可されます WhenSupported 要求が処理のためにアプリケーションに返されます。 サービス名のチェックは自動的に実行されません。 アプリケーションでは、 ServiceName プロパティを使用して独自のサービス名の検証を実行することもできますが、このような状況では冗長になります。
アプリケーションが独自の SSPI 呼び出しを行って、HTTP 要求の本文内でやり取りされる BLOB に基づいて認証を実行し、チャネル バインドをサポートする必要がある場合は、ネイティブ Win32 AcceptSecurityContext 関数に渡すために、HttpListenerを使用して外部のセキュリティで保護されたチャネルから予期されるチャネル バインドを取得する必要があります。 これを行うには、 TransportContext プロパティを使用し、 GetChannelBinding メソッドを呼び出して CBT を取得します。 エンドポイント バインドのみがサポートされています。 他の Endpoint が指定されている場合は、 NotSupportedException がスローされます。 基になるオペレーティング システムがチャネル バインドをサポートしている場合、GetChannelBinding メソッドは、pInput
パラメーターで渡された SecBuffer 構造体の pvBuffer メンバーとして AcceptSecurityContext 関数に渡すために適したチャネル バインドへのポインターをラップするChannelBindingSafeHandleを返します。
Size プロパティには、チャネル バインドの長さ (バイト単位) が含まれます。 基になるオペレーティング システムがチャネル バインドをサポートしていない場合、関数は null
を返します。
もう 1 つの考えられるシナリオは、プロキシが使用されていないときに HTTP://
プレフィックスの拡張保護を有効にすることです。 この場合は、PolicyEnforcementを WhenSupported または Always に設定したExtendedProtectionPolicyにHttpListener.ExtendedProtectionPolicyを設定し、ProtectionScenarioTransportSelected A の値に設定WhenSupported、HttpListenerを部分的に書き込むモードに設定します。一方、Alwaysは完全に強化されたモードに対応します。
許可されるサービス名の既定の一覧は、 HttpListenerに登録されているプレフィックスに基づいて作成されます。 この既定のリストは、 DefaultServiceNames プロパティを使用して調べることができます。 このリストが包括的でない場合、アプリケーションは、既定のサービス名リストの代わりに使用される ExtendedProtectionPolicy クラスのコンストラクターでカスタム サービス名コレクションを指定できます。
この構成では、外部のセキュリティで保護されたチャネル認証なしでサーバーに要求が行われると、通常はチャネル バインド チェックなしで続行されます。 認証が成功すると、クライアントが指定したサービス名のコンテキストが照会され、許容されるサービス名の一覧に対して検証されます。 次の 4 つの結果が考えられます。
サーバーの基になるオペレーティング システムは、拡張保護をサポートしていません。 要求はアプリケーションに公開されず、承認されていない (401) 応答がクライアントに返されます。 エラーの理由を示すメッセージが HttpListener トレース ソースに記録されます。
クライアントの基になるオペレーティング システムは、拡張保護をサポートしていません。 WhenSupported構成では、認証の試行が成功し、要求がアプリケーションに返されます。 Always構成では、認証の試行は失敗します。 要求はアプリケーションに公開されず、承認されていない (401) 応答がクライアントに返されます。 エラーの理由を示すメッセージが HttpListener トレース ソースに記録されます。
クライアントの基になるオペレーティング システムは拡張保護をサポートしていますが、アプリケーションでサービス バインドが指定されていませんでした。 要求はアプリケーションに公開されず、承認されていない (401) 応答がクライアントに返されます。 エラーの理由を示すメッセージが HttpListener トレース ソースに記録されます。
クライアントがサービス バインディングを指定しました。 サービス バインドは、許可されているサービス バインドの一覧と比較されます。 一致する場合、要求はアプリケーションに返されます。 それ以外の場合、要求はアプリケーションに公開されず、承認されていない (401) 応答が自動的にクライアントに返されます。 エラーの理由を示すメッセージが HttpListener トレース ソースに記録されます。
許容されるサービス名の許可されたリストを使用するこの単純な方法が不十分な場合、アプリケーションは、 ServiceName プロパティに対してクエリを実行することで、独自のサービス名の検証を提供する可能性があります。 上記のケース 1 と 2 では、プロパティは null
を返します。 3 の場合、空の文字列が返されます。 ケース 4 では、クライアントによって指定されたサービス名が返されます。
これらの拡張保護機能は、他の種類の要求での認証や、信頼されたプロキシが使用される場合に、サーバー アプリケーションでも使用できます。
こちらも参照ください
.NET