AD FS 2019 リスク評価モデルでプラグインを構築する
独自のプラグインを構築して、さまざまな段階 (要求の受信済み、事前認証、認証後) で認証要求をブロックしたりリスク スコアを割り当てたりすることができるようになりました。 これは AD FS 2019 で導入された新しいリスク評価モデルを使用して実現できます。
リスク評価モデルとは
リスク評価モデルは、開発者が認証要求ヘッダーを読み取り独自のリスク評価ロジックを実装できるようにする、一連のインターフェイスとクラスです。 実装されたコード (プラグイン) は、AD FS 認証プロセスに沿って実行されます。 たとえば、モデルに含まれるインターフェイスとクラスを使用して、要求ヘッダーに含まれるクライアント IP アドレスに基づいて認証要求をブロックまたは許可するコードを実装できます。 AD FS では、認証要求ごとにコードを実行し、実装されたロジックに応じて適切なアクションを実行します。
このモデルでは、次に示すように、AD FS 認証パイプラインの 3 つのいずれかの段階でコードをプラグインできます。
要求の受信済み段階 – AD FS が認証要求を受信するとき、つまりユーザーが資格情報を入力する前に、要求を許可またはブロックするプラグインを構築できます。 この段階で使用できる要求コンテキスト (クライアント IP、Http メソッド、プロキシ サーバー DNS など) を使用して、リスク評価を実行できます。 たとえば、要求コンテキストから IP を読み取り、IP が危険な IP の定義済みの一覧にある場合は認証要求をブロックするプラグインを構築できます。
事前認証段階 – ユーザーが資格情報を提供したが、資格情報が AD FS によって評価される前の時点で、要求を許可またはブロックするプラグインを構築できます。 この段階では、要求コンテキストに加えて、リスク評価ロジックで使用するセキュリティ コンテキスト (ユーザー トークン、ユーザー識別子など) およびプロトコル コンテキスト (認証プロトコル、clientID、resourceID など) に関する情報もあります。 たとえば、ユーザー トークンからユーザー パスワードを読み取り、パスワードが危険なパスワードの定義済みの一覧にある場合は認証要求をブロックすることでパスワード スプレー攻撃を防ぐプラグインを構築できます。
認証後 – ユーザーが資格情報を指定し、AD FS によって認証が実行された後にリスクを評価するプラグインを構築できます。 この段階では、要求コンテキスト、セキュリティ コンテキスト、プロトコル コンテキストに加えて、認証結果 (成功または失敗) に関する情報も得られます。 プラグインでは、使用可能な情報に基づいてリスク スコアが評価され、リスク スコアを要求規則とポリシー規則に渡してさらに評価します。
リスク評価プラグインを構築し、AD FS プロセスに沿って実行する方法をよりよく理解するために、危険として識別された特定のエクストラネットの IP からの要求をブロックするサンプル プラグインを構築し、プラグインを AD FS に登録し、最後に機能をテストしてみましょう。
Note
または、Microsoft Entra ID 保護によって決定されたユーザー リスク レベルを利用して認証のブロックまたは Multi-Factor Authentication (MFA) の実施を行うサンプル プラグインである、危険なユーザー プラグインを構築することもできます。 危険なユーザー プラグインを構築する手順については、こちらを参照してください。
サンプル プラグインの構築
注意
このチュートリアルは、サンプル プラグインを作成する方法を説明するためだけのものです。 作成するソリューションは、エンタープライズに対応したソリューションではありません。
前提条件
このサンプル プラグインを構築するために必要な前提条件の一覧を次に示します。
- AD FS 2019 がインストールおよび構成されている
- .NET Framework 4.7 以上
- Visual Studio
プラグイン dll を構築する
次の手順では、サンプル プラグイン dll の構築について説明します。
サンプル プロジェクトをダウンロードします。Git Bash を使用して、次のように入力します。
git clone https://github.com/Microsoft/adfs-sample-RiskAssessmentModel-RiskyIPBlock
AD FS サーバー上の任意の場所に .csv ファイルを作成し (この場合は、C:\extensions に authconfigdb.csv ファイルを作成)、ブロックする IP をこのファイルに追加します。
このサンプル プラグインでは、このファイルに記載されている エクストラネットの IP からの認証要求がブロックされます。
注意
AD FS ファームがある場合は、任意またはすべての AD FS サーバーにファイルを作成できます。 任意のファイルを使用して、危険な IP を AD FS にインポートできます。 インポート プロセスの詳細については、以下の「プラグイン dll を AD FS に登録する」セクションで説明します。
Visual Studio を使用して、プロジェクト
ThreatDetectionModule.sln
を展開します。以下に示すように、
Microsoft.IdentityServer.dll
をソリューション エクスプローラーから削除します。以下に示すように、AD FS の
Microsoft.IdentityServer.dll
への参照を追加します。a. ソリューション エクスプローラーで [参照] を右クリックし、[参照の追加…] を選択します。
b. [参照マネージャー] ウィンドウで、[参照] を選択します。 [参照するファイルの選択...] ダイアログで、AD FS インストール フォルダーから
Microsoft.IdentityServer.dll
を選択し (この場合は C:\Windows\ADFS)、[追加] をクリックします。注意
この場合は、AD FS サーバー自体にプラグインを構築しています。 開発環境が別のサーバー上にある場合は、AD FS サーバー上の AD FS インストール フォルダーから開発ボックスに
Microsoft.IdentityServer.dll
をコピーします。c. [参照マネージャー] ウィンドウで、
Microsoft.IdentityServer.dll
チェック ボックスがオンになっていることを確認した後、 [OK] をクリックします。構築を行うために、すべてのクラスと参照が配置されました。 ただし、このプロジェクトの出力は dll であるため、AD FS サーバーのグローバル アセンブリ キャッシュ (GAC) にインストールする必要があり、dll は最初に署名する必要があります。 そのためには、次の手順に従います。
a. プロジェクトの名前 ThreatDetectionModule を右クリックします。 メニューの [プロパティ] をクリックします。
b. [プロパティ] ページで、左側の [署名] をクリックし、[アセンブリに署名する] とマークされたチェック ボックスをオンにします。 [厳密な名前のキー ファイルを選択してください:] というプルダウン メニューから、[<新規...>] を選択します。
c. [厳密な名前のキーの作成] ダイアログで、キーの名前 (任意の名前を選択できます) を入力し、[パスワードでキー ファイルを保護する] チェック ボックスをオフにします。 [OK] をクリックします。
d. 次に示すように、プロジェクトを保存します。
次に示すように、[ビルド] をクリックし、[ソリューションのリビルド] をクリックしてプロジェクトをビルドします。
画面の下部にある [出力] ウィンドウを確認して、エラーが発生したかどうか確認します。
プラグイン (dll) を使用する準備が整い、プロジェクト フォルダーの \bin\Debug フォルダーにあります (この場合は C:\extensions\ThreatDetectionModule\bin\Debug\ThreatDetectionModule.dll)。
次の手順では、この dll を AD FS に登録して、AD FS 認証プロセスに沿って実行するようにします。
プラグイン dll を AD FS に登録する
AD FS サーバーで Register-AdfsThreatDetectionModule
PowerShell コマンドを使用して、dll を AD FS に登録する必要があります。 ただし、登録する前に、公開キー トークンを取得する必要があります。 この公開キー トークンは、キーを作成し、そのキーを使用して dll に署名するときに作成されました。 dll の公開キー トークンが何であるかについて学習するには、次のように SN.exe を使用します。
dll ファイルを \bin\Debug フォルダーから別の場所にコピーします (この場合は C:\extensions にコピーします)。
Visual Studio の開発者コマンド プロンプトを起動し、sn.exe を含むディレクトリに移動します (この場合、ディレクトリは C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools です)。
-T パラメーターとファイルの場所を指定して SN コマンドを実行します (この場合、
SN -T "C:\extensions\ThreatDetectionModule.dll"
)。コマンドによって公開キー トークンが提供されます (この場合、公開キー トークンは 714697626ef96b35)
AD FS サーバーのグローバル アセンブリ キャッシュに dll を追加します。ベスト プラクティスは、プロジェクト用の適切なインストーラーを作成し、インストーラーを使用してファイルを GAC に追加することです。 もう 1 つの解決策は、開発用コンピューターで Gacutil.exe を使用することです (Gacutil.exe の詳細についてはこちらを参照してください)。 この場合、Visual Studio は AD FS と同じサーバー上にあるため、Gacutil.exe を次のように使用します。
a. Visual Studio の開発者コマンド プロンプトで、Gacutil.exe を含むディレクトリに移動します (この場合、ディレクトリは C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools です)。
b. Gacutil コマンドを実行します (この場合、
Gacutil /IF C:\extensions\ThreatDetectionModule.dll
)。Note
AD FS ファームがある場合、ファーム内の各 AD FS サーバーで上記を実行する必要があります。
Windows PowerShell を開き、次のコマンドを実行して dll を登録します。
Register-AdfsThreatDetectionModule -Name "<Add a name>" -TypeName "<class name that implements interface>, <dll name>, Version=10.0.0.0, Culture=neutral, PublicKeyToken=< Add the Public Key Token from Step 2. above>" -ConfigurationFilePath "<path of the .csv file>"
この場合、コマンドは次のようになります。
Register-AdfsThreatDetectionModule -Name "IPBlockPlugin" -TypeName "ThreatDetectionModule.UserRiskAnalyzer, ThreatDetectionModule, Version=10.0.0.0, Culture=neutral, PublicKeyToken=714697626ef96b35" -ConfigurationFilePath "C:\extensions\authconfigdb.csv"
注意
AD FS ファームを使用している場合でも、dll の登録は 1 回だけ必要です。
dll を登録した後、AD FS サービスを再起動します。
これで dll が AD FS に登録され、使用する準備ができました。
注意
プラグインに変更が加えられ、プロジェクトが再構築された場合は、更新された dll を再登録する必要があります。 登録する前に、次のコマンドを使用して現在の dll の登録を解除する必要があります。
UnRegister-AdfsThreatDetectionModule -Name "<name used while registering the dll in 5. above>"
この場合、コマンドは次のようになります。
UnRegister-AdfsThreatDetectionModule -Name "IPBlockPlugin"
プラグインのテスト
前の手順で作成した authconfig.csv ファイルを開き (この場合、C:\extensions にあります)、ブロックするエクストラネット IP を追加します。 すべての IP は別々の行に記載する必要があり、末尾にスペースを入れないでください。
ファイルを保存して閉じます。
次の PowerShell コマンドを実行して、更新されたファイルを AD FS にインポートします。
Import-AdfsThreatDetectionModuleConfiguration -name "<name given while registering the dll>" -ConfigurationFilePath "<path of the .csv file>"
この場合、コマンドは次のようになります。
Import-AdfsThreatDetectionModuleConfiguration -name "IPBlockPlugin" -ConfigurationFilePath "C:\extensions\authconfigdb.csv")
authconfig.csv に追加したものと同じ IP アドレスを使用するサーバーから認証要求を開始します。
このデモでは、AD FS Help Claims X-Ray ツールを使用して要求を開始します。 X-Ray ツールを使用する場合は、指示に従ってください。
フェデレーション サーバー インスタンスを開始し、[認証のテスト] ボタンをクリックします。
次に示すように、認証がブロックされます。
これで、プラグインをビルドして登録する方法がわかりました。次は、モデルで導入された新しいインターフェイスとクラスを使用した実装を理解するために、プラグイン コードについて説明します。
プラグイン コードのチュートリアル
Visual Studio を使用してプロジェクト ThreatDetectionModule.sln
を開き、画面の右側にあるソリューション エクスプローラーからメイン ファイル UserRiskAnalyzer.cs を開きます。
このファイルには、抽象クラス ThreatDetectionModule とインターフェイス IRequestReceivedThreatDetectionModule を実装するメイン クラス UserRiskAnalyzer が格納されています。このクラスは、要求コンテキストから IP を読み取り、取得した IP と AD FS DB から読み込まれた IP を比較し、IP が一致した場合は要求をブロックします。 これらの型について、さらに詳しく説明します。
ThreatDetectionModule 抽象クラス
この抽象クラスは、プラグインを AD FS パイプラインに読み込み、AD FS プロセスに沿ってプラグイン コードを実行できるようにします。
public abstract class ThreatDetectionModule
{
protected ThreatDetectionModule();
public abstract string VendorName { get; }
public abstract string ModuleIdentifier { get; }
public abstract void OnAuthenticationPipelineLoad(ThreatDetectionLogger logger, ThreatDetectionModuleConfiguration configData);
public abstract void OnAuthenticationPipelineUnload(ThreatDetectionLogger logger);
public abstract void OnConfigurationUpdate(ThreatDetectionLogger logger, ThreatDetectionModuleConfiguration configData);
}
クラスには、次のメソッドとプロパティが含まれています。
Method | Type | 定義 |
---|---|---|
OnAuthenticationPipelineLoad | Void | プラグインがパイプラインに読み込まれるときに AD FS によって呼び出されます |
OnAuthenticationPipelineUnload | Void | プラグインがパイプラインからアンロードされるときに AD FS によって呼び出されます |
OnConfigurationUpdate | Void | 構成の更新時に AD FS によって呼び出されます |
Property | Type | 定義 |
VendorName | String | プラグインを所有しているベンダーの名前を取得します |
ModuleIdentifier | String | プラグインの識別子を取得します |
このサンプル プラグインでは、OnAuthenticationPipelineLoad メソッドと OnConfigurationUpdate メソッドを使用して、事前定義された IP を AD FS DB から読み取ります。 OnAuthenticationPipelineLoad は、プラグインが AD FS に登録されるときに呼び出され、OnConfigurationUpdate は、Import-AdfsThreatDetectionModuleConfiguration
コマンドレットを使用して .csv をインポートするときに呼び出されます。
IRequestReceivedThreatDetectionModule インターフェイス
このインターフェイスを使用すると、AD FS が認証要求を受信するが、ユーザーが資格情報を入力する前の時点、つまり認証プロセスの受信済み要求ステージで、リスク評価を実装できます。
public interface IRequestReceivedThreatDetectionModule
{
Task<ThrottleStatus> EvaluateRequest (
ThreatDetectionLogger logger,
RequestContext requestContext );
}
このインターフェイスには EvaluateRequest メソッドが含まれており、このメソッドにより、requestContext 入力パラメーターで渡される認証要求のコンテキストを使用して、リスク評価ロジックを記述できます。 requestContext パラメーターの型は RequestContextです。
渡されるもう 1 つの入力パラメーターは、ThreatDetectionLogger 型のロガーです。 このパラメーターを使用すると、エラー、監査、およびデバッグ メッセージを AD FS ログに書き込むことができます。
このメソッドにより、ThrottleStatus (NotEvaluated の場合は 0、ブロックの場合は 1、許可の場合は 2) が AD FS に返され、その後 AD FS では要求がブロックまたは許可されます。
このサンプル プラグインでは、EvaluateRequest メソッド実装によって requestContext パラメーターからの clientIpAddress が解析され、AD FS DB から読み込まれたすべての IP と比較されます。 一致が見つかった場合、メソッドでは Block として 2 が返され、それ以外の場合は Allow として 1 が返されます。 返された値に基づいて、AD FS で要求がブロックまたは許可されます。
注意
上記で説明したサンプル プラグインは、IRequestReceivedThreatDetectionModule インターフェイスのみを実装します。 ただし、リスク評価モデルには、IPreAuthenticationThreatDetectionModule (事前認証段階でリスク評価ロジックを実装する) と IPostAuthenticationThreatDetectionModule (認証後の段階でリスク評価ロジックを実装する) という 2 つの追加のインターフェイスが用意されています。 この 2 つのインターフェイスの詳細については、以下を参照してください。
IPreAuthenticationThreatDetectionModule インターフェイス
このインターフェイスを使用すると、ユーザーが資格情報を提供したが、AD FS によって評価される前の時点 (つまり事前認証段階) でリスク評価ロジックを実装することができます。
public interface IPreAuthenticationThreatDetectionModule
{
Task<ThrottleStatus> EvaluatePreAuthentication (
ThreatDetectionLogger logger,
RequestContext requestContext,
SecurityContext securityContext,
ProtocolContext protocolContext,
IList<Claim> additionalClams
);
}
このインターフェイスには、 EvaluatePreAuthentication メソッドが含まれており、このメソッドにより、RequestContext requestContext、SecurityContext securityContext、ProtocolContext protocolContext、および IList<Claim> additionalClams 入力パラメーターで渡される情報を使用して、事前認証のリスク評価ロジックを記述することができます。
注意
各コンテキストの種類で渡されるプロパティの一覧については、RequestContext、SecurityContext、および ProtocolContext クラスの定義を参照してください。
渡されるもう 1 つの入力パラメーターは、ThreatDetectionLogger 型のロガーです。 このパラメーターを使用すると、エラー、監査、およびデバッグ メッセージを AD FS ログに書き込むことができます。
このメソッドにより、ThrottleStatus (NotEvaluated の場合は 0、ブロックの場合は 1、許可の場合は 2) が AD FS に返され、その後 AD FS では要求がブロックまたは許可されます。
IPostAuthenticationThreatDetectionModule インターフェイス
このインターフェイスを使用すると、ユーザーが資格情報を提供し、AD FS によって認証された後、つまり認証後段階で、リスク評価ロジックを実装できます。
public interface IPostAuthenticationThreatDetectionModule
{
Task<RiskScore> EvaluatePostAuthentication (
ThreatDetectionLogger logger,
RequestContext requestContext,
SecurityContext securityContext,
ProtocolContext protocolContext,
AuthenticationResult authenticationResult,
IList<Claim> additionalClams
);
}
このインターフェイスには、 EvaluatePostAuthentication メソッドが含まれており、このメソッドにより、RequestContext requestContext、SecurityContext securityContext、ProtocolContext protocolContext、および IList<Claim> additionalClams 入力パラメーターで渡される情報を使用して、認証後のリスク評価ロジックを記述することができます。
注意
各コンテキストの種類で渡されるプロパティのすべての一覧については、RequestContext、SecurityContext、および ProtocolContext クラスの定義を参照してください。
渡されるもう 1 つの入力パラメーターは、ThreatDetectionLogger 型のロガーです。 このパラメーターを使用すると、エラー、監査、およびデバッグ メッセージを AD FS ログに書き込むことができます。
メソッドでは、AD FS ポリシーと要求規則で使用できるリスク スコアが返されます。
注意
プラグインを機能させるには、メイン クラス (この場合は UserRiskAnalyzer) は ThreatDetectionModule 抽象クラスを派生する必要があり、上記の 3 つのインターフェイスのうち少なくとも 1 つを実装する必要があります。 dll が登録されると、AD FS では実装されているインターフェイスが検査され、パイプラインの適切な段階でそれらが呼び出されます。
FAQ
これらのプラグインを作成する必要があるのはなぜですか。
A:これらのプラグインでは、パスワード スプレー攻撃などの攻撃から環境を保護するための追加機能が提供されるだけでなく、お客様の要件に基づいて独自のリスク評価ロジックを構築するための柔軟性も提供されます。
ログはどこでキャプチャされますか。
A: WriteAdminLogErrorMessage メソッドを使用して "AD FS/Admin" イベント ログにエラー ログを書き込み、WriteAuditMessage メソッドを使用して "AD FS の監査" セキュリティ ログに監査ログを書き込み、WriteDebugMessage メソッドを使用して "AD FS トレース" デバッグ ログにデバッグ ログを書き込むことができます。
これらのプラグインを追加すると、AD FS 認証プロセスの待機時間が増加しますか?
A:待機時間の影響は、実装するリスク評価ロジックの実行にかかった時間によって決まります。 運用環境にプラグインを展開する前に、待機時間の影響を評価することをお勧めします。
危険な IP やユーザーなどの一覧を AD FS で提案できないのはなぜですか?
A:現在は利用できませんが、プラグ可能なリスク評価モデルで危険な IP やユーザーなどを提案するためのインテリジェンスを構築することに取り組んでいます。 近日中に発表日をお知らせします。
他にどんなサンプル プラグインを利用できますか?
A:次のサンプル プラグインを利用できます。
Name | 説明 |
---|---|
危険なユーザー プラグイン | Microsoft Entra ID 保護によって決定されるユーザー リスク レベルに基づいて、認証をブロックするか MFA を実施するサンプル プラグイン。 |