2

ユーザーがパスワード リセット機能ページから Active Directory パスワードを変更できるようにする MVC 4 アプリケーションがあります。新しいパスワードを設定する次のコードがあります。

 DirectoryEntry de = sr.GetDirectoryEntry();
 de.Invoke("SetPassword", new object[] { newPassword });
 de.Properties["LockOutTime"].Value = 0;

新しいパスワードの詳細を含むフォームを送信しようとすると、次のエラーがアプリケーション イベント ログに書き込まれます。

 0x80070005 (E_ACCESSDENIED))

アプリケーション プールの Identity プロパティを NetworkService に設定し、これで接続の問題が解決されると考えていました。ASPNET アプリケーションが AD に接続できるようにするために、他に確認する必要があることはありますか。

4

1 に答える 1

1

tl;dr

私たちの場合、これはランダムに発生し始めました。これは、自己署名 SSL 証明書の有効期限が切れたためです。IIS で新しいものを作成した後、問題は解決しました。

説明

このスレッドは私を原因に導きます。

SetPasswordなぜそれが必要なのかがわかるように、ここで何をするのかを簡単に要約します。その特定の ADSI メソッドは、実際には 3 つのメソッドをカバーの下にバンドルしています。最初に、LDAP を使用して安全な SSL チャネルを介してパスワードを設定しようとします。次に、Kerberos set password プロトコルを使用して設定を試みます。最後に、 を使用NetUserSetInfoして設定を試みます。

主な問題は、最初の 2 つの方法のみが、一般に .xml ファイルに入力した資格情報を尊重することですDirectoryEntryたとえば、適切な資格情報と SSL チャネルを提供すると、LDAP パスワード変更メカニズムはそれらの資格情報で機能します...

NetUserSetInfo メソッドを確認すると、認証用のユーザー名/パスワードを入力する場所がないことがわかります。つまり、アンマネージ スレッドのセキュリティ コンテキストしか使用できません。つまり、機能させるには、最初にプログラムで提供したユーザー名とパスワードの組み合わせを偽装する必要があります...

LDAP over SSL は明らかに最善の方法であり (そして私たちが使用していた方法でした)、自己署名 SSL 証明書の有効期限が切れると、Kerberos をスキップして にフォールバックしNetUserSetInfo、失敗したようです (説明を歓迎します)。私たちが提供した資格情報を使用していなかったためです。(または、投稿者がKerberosに渡された資格情報を見たことがないと言ったため、Kerberosで失敗しただけです)

そのため、新しい自己署名証明書 ( 用COMPUTER.DOMAIN.local) を作成した後、問題は解決されました。

コードは次のとおりです(誰かが探している場合に備えて):

DirectoryEntry myDE = new DirectoryEntry(@"LDAP://OU=GroupName,DC=DOMAIN,DC=local");
myDE.Username = "administrator";
myDE.Password = "adminPassword";
DirectoryEntries myEntries = myDE.Children;
DirectoryEntry myDEUser = myEntries.Find("CN=UserName");

myDEUser.Invoke("SetPassword", new object[] { "NewPassword" });
myDEUser.Properties["LockOutTime"].Value = 0;
// the following 2 lines are free =)
myDEUser.Properties["userAccountControl"].Value = (int)myDEUser.Properties["userAccountControl"].Value | 0x10000;  // don't expire password
myDEUser.Properties["userAccountControl"].Value = (int)myDEUser.Properties["userAccountControl"].Value & ~0x0002;  // ensure account is enabled
myDEUser.CommitChanges();
于 2014-01-08T19:22:36.660 に答える