1. ホーム
  2. c#

[解決済み] ドメイン認証の検証方法は?

2023-02-25 23:09:48

質問

私は、ドメインコントローラに対して一連の資格情報を検証したい。

Username: STACKOVERFLOW\joel
Password: splotchy

方法1.なりすましでActive Directoryに問い合わせる

多くの人が、Active Directory に何か問い合わせることを提案しています。例外がスローされた場合、資格情報が有効でないことがわかります (下記で提案されているとおりです)。 このスタックオーバーフローの質問 .

いくつかの深刻な の欠点があります。 があります。

  1. ドメイン アカウントを認証しているだけでなく、暗黙的な認証チェックも行っています。つまり、なりすましトークンを使用して AD からプロパティを読み取っています。そうでなければ有効なアカウントに、AD から読み取る権利がない場合はどうなるでしょうか。デフォルトでは、すべてのユーザーは読み取りアクセス権を持っていますが、ドメインポリシーは、制限されたアカウント(およびまたはグループ)のアクセス許可を無効にするように設定することができます。

  2. AD に対するバインディングには深刻なオーバーヘッドがあり、AD スキーマ キャッシュはクライアント (DirectoryServices によって使用される ADSI プロバイダーの ADSI キャッシュ) でロードされる必要があります。これは、ネットワークと AD サーバーの両方のリソースを消費し、ユーザー アカウントを認証するような単純な操作には高すぎます。

  3. あなたは、例外的でないケースの例外的な失敗に依存しており、それが無効なユーザー名とパスワードを意味すると仮定しています。そして、他の問題 (ネットワーク障害、AD 接続障害、メモリ割り当てエラーなど) を認証障害と誤って解釈しています。

方法 2. LogonUser Win32 API

その他 を使用することを提案しています。 LogonUser() API関数を使うことを提案しました。これは素晴らしく聞こえますが、残念ながら、呼び出すユーザーは、通常オペレーティング システム自体にのみ与えられている権限を必要とすることがあります。

LogonUserを呼び出すプロセスには SE_TCB_NAME 特権が必要です。もし 呼び出したプロセスがこの特権を持っていない場合 権限を持たない場合、LogonUser は失敗し GetLastErrorは error_privilege_not_heldを返します。

いくつかの を呼び出すプロセスは、場合によっては LogonUserを呼び出すプロセスも SE_CHANGE_NOTIFY_NAME 特権が有効でなければなりません。 そうでない場合、LogonUser は失敗し は失敗し、GetLastError は error_access_denied を返します。この特権は ローカル・システム・アカウントまたはそのメンバーであるアカウントには必要ありません。 アカウント、または管理者グループのメンバーであるアカウントには必要ありません。 この特権は、ローカルのシステム・アカウント、または administrators グループのメンバーであるアカウントには必要ありません。デフォルトでは デフォルトでは、SE_CHANGE_NOTIFY_NAMEはすべてのユーザーに対して有効です。 すべてのユーザーに対して有効ですが、管理者によっては 管理者によっては、すべてのユーザーに対してこれを無効にすることができます。 を無効にすることもできます。

配布するのは、"です。 オペレーティング システムの一部として機能する 特権を与えることは、やみくもに行うべきことではありません。 ナレッジベースの記事 :

<ブロッククオート

...このプロセスでは を呼び出しているプロセスには、SE_TCB_NAME 権限を持っている必要があります (ユーザー マネージャで、これは は、" オペレーティング システムの一部としての行為 システム "右)。SE_TCB_NAME 特権は非常に強力で を実行できるようにするために、任意のユーザに与えるべきではありません。 アプリケーションを実行するために が必要なアプリケーションを実行するために を実行できるようにするためです。

さらに LogonUser() の呼び出しは、空白のパスワードが指定された場合、失敗します。


ドメイン認証情報のセットを認証するための適切な方法は何ですか?


I 起こる はマネージ コードから呼び出していますが、これは一般的な Windows の質問です。顧客が .NET Framework 2.0 をインストールしていると仮定することができます。

どのように解決するのですか。

.NET 3.5でC#を使用して System.DirectoryServices.AccountManagementを使用します。 .

 bool valid = false;
 using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
 {
     valid = context.ValidateCredentials( username, password );
 }

これは現在のドメインに対してバリデーションを行います。 他のオプションについては、パラメータ化されたPrincipalContextのコンストラクタをチェックしてください。