c#更改AD密码Directoryservices

我试图让以下代码工作,问题是,有时它确实,有时它没有。 当它失败时,它会给出错误0x800704F1“系统无法联系域控制器来为身份validation请求提供服务”我说它有90%的时间失败。 我已经尝试通过在上下文类型后添加它来给它一个静态DC这可悲的没有帮助。 在管理员用户,它总是工作..但我相信用户应该能够更改自己的密码。 在user.changepassword行上触发错误

我希望别人有一个好主意。

using (var context = new PrincipalContext(ContextType.Domain)) { using (var user = UserPrincipal.Current) { try { user.ChangePassword(txt_old.Text, txt_new.Text); user.Save(); } catch(Exception p) { if (p.HResult.Equals("0x800708C5"))//Not secure enough according to password policy { MessageBox.Show("Volgens het systeem is uw nieuwe wachtwoord niet veilig genoeg, voldoet het aan alle eisen?", "Niet gelukt", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } else if (p.HResult.Equals("0x80070056")) //Wrong current password { MessageBox.Show("U heeft een verkeerd huidig wachtwoord ingevult, probeer het nogmaals", "Verkeerd wachtwoord", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } else if (p.InnerException.ToString().Contains("0x80070775")) //Temporarly locked out. { MessageBox.Show("Uw account is tijdelijk vergrendeld door te veel pogingen tot in te loggen met een foutief wachtwoord. Probeer het over 15minuten nogmaals of neem contact op met de helpdesk.", "vergrendeld.", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } else { MessageBox.Show(System.Security.Principal.WindowsIdentity.GetCurrent().Name + Environment.NewLine + p.HResult + Environment.NewLine + p.Message); return; } } } } 

两个Windows更新3177108和3167679已更改ChangePassword的行为。

这里有一个关于这个问题的post: https : //social.msdn.microsoft.com/Forums/vstudio/en-US/77dc733e-a13d-4349-9088-8065b85d5c3f/userprincipalchangepassword-stops-working-after-windows-updates -3177108和-3167679?论坛= netfxbcl

看来,您现在必须在创建PrincipalContext时指定有效的UPN。

在创建上下文之前,您可以使用IP作为端点,现在看来它必须是正确的域名。

此外,您现在总是在发生错误时收到相同的exception – 我们曾经为选择密码不足的用户收到密码策略例外,现在我们得到:

System.DirectoryServices.AccountManagement.PrincipalOperationException:系统无法联系域控制器来为身份validation请求提供服务。 请稍后再试。 (HRESULTexception:0x800704F1)

更新04-10-2016:上面显示的exception实际上是在更新后调用ChangePassword时收到的一般/一般错误。 例如,如果协议中涉及的某些端口被防火墙阻止,您也可以获得此端口(如果您从未加入域的服务器/计算机上调用,则适用)。

所需端口的良好资源: https : //technet.microsoft.com/en-us/library/dd772723(v = ws.10).aspx请注意,动态范围也是必需的。

如果不允许用户更改密码(域策略,通过设置下一次登录标记必须更改),您也会收到此exception。

您的问题可能是发生了密码策略违规。 也就是说,例如,如果你有一个密码策略,用户无法将他们的密码更改为他们的最后一个5,例如,如果他们尝试更改为他们的最后5个之一,你会看到这个在我的经历中抛出错误。

您报告的exception(在我的情况下)之前的错误如下所示:TargetInvocationException:尝试更改Active Directory密码时出现COM错误。

因此,我会检查您的密码政策,并确保您的用户在这些情况下没有违反它。

更新:2016年10月10日:Microsoft已更新此文章: https : //support.microsoft.com/en-us/kb/3177108 。 在这里,他们给了我们原始“修复”创建的问题以及使用Kerberos和自助密码重置的一些技巧。

截至2016年10月11日,Microsoft重新发布了与https://technet.microsoft.com/en-us/library/security/ms16-101.aspx相关的修补程序,以解决原始更新引起的问题(您可以阅读在https://support.microsoft.com/en-us/kb/3177108中,包括您无法再更改本地帐户的密码这一事实。


我相信我有答案。 Microsoft最近修补了Windows,因此NTLM不能再用于更改密码了。

解决方案#1(“锤子”):尝试在运行代码的服务器上删除其中一个或两个KB更新。

https://support.microsoft.com/en-us/kb/3177108

https://support.microsoft.com/en-us/kb/3167679

如果您说您可以更改管理员密码,那么您的意思是仅当您的表单应用程序在管理员的计算机上运行时? 应用程序在非管理员计算机上运行时是否存在挑战?

我能够使用您的代码并使其正常工作以及更改以下内容:

 using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "test.user0001")) 

 using (var user = UserPrincipal.FindByIdentity(context, IdentityType.UserPrincipalName, "test.user0001@webactivedirectory.com")) 

使用这些行中的任何一行以及您的(获得当前用户)我能够更改管理员和非管理员密码。 我的问题是,当您在非管理员计算机上运行表单应用程序时是否发生了错误。

我在两个不同的场合从系统管理员方面目睹了这一点:必须在两个新部署的服务器上安装两个具有密码管理function的应用程序,这些服务器当然已完全修补; 在这两种情况下,更改密码失败,并显示有关应用程序无法联系域控制器的错误(当然,实际上存在且可用)。

一个应用程序是闭源供应商提供的( Cyber​​Ark的特权会话管理器 ),而另一个是我正在工作的客户开发的内部应用程序; 在第二种情况下,我能够看一下代码,它确实类似于原始问题中使用的代码。

遗憾的是,实际修复代码在两种情况下都不是一个选项:对于第一个应用程序,我们必须向应用程序供应商报告错误,而对于第二个应用程序,我们必须向处理应用程序的内部开发团队报告错误,在任何一种情况下,我们都无法立即解决问题。 管理层希望这两个应用程序现在正在运行 ,因此我们不得不删除有问题的更新(我知道,这很糟糕,不是解决方案,而是一种懒惰和危险的解决方法,我尽我所能避免这种情况;但管理层是管理层,所以。 .. meh)。

无论如何,我之所以提到这个答案:除了删除KB3177108和KB3167679之外 ,在我的情况下(两种情况)我们还必须删除KB3175024和KB3174644 ; 虽然安装了这两个更新,但密码更改function仍然拒绝工作,即使在删除前两个更新后也是如此。

因此,如果您发现自己处于无法修复代码的情况,并且删除KB3177108和KB3167679无法解决问题,那么您也可以尝试删除KB3175024和KB3174644。