c#更改AD密码Directoryservices

时间:2016-08-16 07:45:52

标签: c# active-directory

我试图让下面的代码工作,问题是,有时它确实如此,有时它不会。 当它失败时它会给出错误0x800704F1"系统无法联系域控制器来为认证请求提供服务" 我说它失败了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;
                    }
                }
            }
        }

4 个答案:

答案 0 :(得分:9)

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

此处有一个关于此问题的主题:https://social.msdn.microsoft.com/Forums/vstudio/en-US/77dc733e-a13d-4349-9088-8065b85d5c3f/userprincipalchangepassword-stops-working-after-windows-updates-3177108-and-3167679?forum=netfxbcl

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

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

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

  

System.DirectoryServices.AccountManagement.PrincipalOperationException:   系统无法联系域控制器进行维护   验证请求。请稍后再试。 (例外   HRESULT:0x800704F1)

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

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

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

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:2)

更新:2016年12月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"))

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

答案 3 :(得分:1)

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

一个应用程序是闭源供应商提供的(CyberArk's Privileged Session Manager),而另一个是我正在工作的客户开发的内部应用程序;在第二种情况下,我能够看一下代码,它确实与原始问题中的代码类似。

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

无论如何,我之所以提到这个答案:除了删除KB3177108KB3167679,在我的情况下(两种情况)我们还必须删除KB3175024和{ {3}};安装了这两个更新后,即使删除了前两个更新,密码更改功能仍然无法正常工作。

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

相关问题