Código fuente completo en C# (C Sharp de Visual Studio .NET Community 2019) de una aplicación que permite cambiar la contraseña de un usuario en el Directorio Activo (Active Directory) de un Dominio Windows Server (LDAP). Permite que un usuario sin privilegios elevados pueda cambiar su contraseña en el dominio.
- Requisitos para desarrollar aplicación C# que cambia la contraseña de usuario LDAP Active Directory.
- Crear solución C# C Sharp en Visual Stduio .Net para cambio de contraseña de un usuario LDAP Active Directory.
- La aplicación Resetear/Restablecer contraseña Active Directory en funcionamiento.
- Descarga del código fuente completo de la aplicación C# para restablecer la contraseña de un usuario de LDAP Active Directory.
- Algunos errores al restablecer/cambiar la contraseña de un usuario LDAP Active Directory.
Requisitos para desarrollar aplicación C# que cambia la contraseña de usuario LDAP Active Directory
El único requisito será disponer del IDE de desarrollo Microsoft Visual Studio Community 2019 (o cualquier otra versión).
En los siguientes enlaces explicamos como instalar Visual Studio .Net y realizar una aplicación simple de prueba:
- Instalar Visual Studio Community 2017 y primera aplicación.
- Instalar Microsoft Visual Studio .NET Community 2015 primera aplicación C#.
También necesitaremos disponer de un dominio en nuestra organización, con Windows Server 2008 en adelante (2012, 2016, 2019), un Directorio Activo (Active Directory), el LDAP de Microsoft. En los siguientes enlaces explicamos cómo montar un servidor de Directorio Activo:
- Servicios de dominio de Active Directory Windows Server 2012 controlador dominio.
- Instalar Active Directory, promocionar controlador dominio, Windows Server 2008.
Crear solución C# C Sharp en Visual Stduio .Net para cambio de contraseña de un usuario LDAP Active Directory
Abriremos Visual Studio .Net, pulsaremos en «Crear un proyecto» y elegiremos «Aplicación de Windows Forms (.NET Framework):
Introduciremos el nombre y la ubicación de la solución, en nuestro caso «ProyectoAResetearContrasenaAD». Dejaremos el .NET Framework por defecto, que en nuestro caso es el .NET Framework 4.7.2. Esta será la versión mínima que necesitará la aplicación para ejecutarse:
Crearemos un formulario con los siguientes componentes:
Desde el menú «Proyecto» [1], pulsaremos en «Agregar referencia…» [2]:
Marcaremos las referencias:
- System.DirectoryServices.
- System.DirectoryServices.AccountManagement.
Principalmente la segunda, en negrita, es la que necesitará nuestra solución para poder ejecutarse.
Y pulsaremos «Aceptar»:
Agregaremos el código fuente, que a continuación mostramos, al formulario formPrincipal.cs (para el evento Click de los botones de cambiar contraseña y de salir y el método para cambiar la contraseña):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
using System; using System.DirectoryServices; using System.DirectoryServices.AccountManagement; using System.Windows.Forms; namespace ResetearContrasenaAD { public partial class formPrincipal : Form { static DirectoryEntry srvLDAPActiveDirectory; public formPrincipal() { InitializeComponent(); } private void btCambiarContrasena_Click(object sender, EventArgs e) { if (txtContrasenaNueva2.Text != txtContrasenaNueva.Text) { MessageBox.Show("Las contraseñas no coinciden.", "Repetir contraseñas...", MessageBoxButtons.OK, MessageBoxIcon.Warning); txtContrasenaNueva.Focus(); } else { if (txtDominio.Text == "") { MessageBox.Show("Debe indicar el dominio LDAP.", "Dominio...", MessageBoxButtons.OK, MessageBoxIcon.Warning); txtDominio.Focus(); } else { if (txtUsuario.Text == "" || txtContrasenaActual.Text == "") { MessageBox.Show("Debe indicar el usuario y la contraseña actuales.", "Usuario y contraseña...", MessageBoxButtons.OK, MessageBoxIcon.Warning); txtUsuario.Focus(); } else { if (txtContrasenaNueva.Text == "") { MessageBox.Show("Debe indicar la nueva contraseña.", "Nueva contraseña...", MessageBoxButtons.OK, MessageBoxIcon.Warning); txtContrasenaNueva.Focus(); } else { if (CambiarContrasenaUsuarioLDAP(txtDominio.Text, txtUsuario.Text, txtContrasenaActual.Text, txtContrasenaNueva.Text)) { Application.Exit(); } //CambiarContrasenaUsuarioLDAPConPrivilegios(txtDominio.Text, txtUsuario.Text, // txtContrasenaActual.Text, txtContrasenaNueva.Text); } } } } } //Cambia la contraseña de un usuario en dominio Active Directory LDAP //Devuelve true si la ha cambiado, false si no ha podido cambiarla public static bool CambiarContrasenaUsuarioLDAP(string dominio, string nombreUsuario, string contrasenaAnterior, string contrasenaNueva) { try { using (var context = new PrincipalContext(ContextType.Domain, dominio)) using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, nombreUsuario)) { user.ChangePassword(contrasenaAnterior, contrasenaNueva); MessageBox.Show("La contraseña se ha cambiado correctamente. " + Environment.NewLine + Environment.NewLine + "Le recomendamos que cierre sesión en el equipo y " + "vuelva a acceder con la nueva contraseña.", "Contraseña cambiada...", MessageBoxButtons.OK, MessageBoxIcon.Information); return true; } } catch (Exception ex) { MessageBox.Show("No se ha podido cambiar la contraseña. Se " + "ha producido el siguiente error: " + Environment.NewLine + Environment.NewLine + ex.Message, "Error...", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } } //Método para cambiar contraseña en LDAP //Funciona pero requiere de privilegios elevados //del usuario en el dominio para cambiar la contraseña public void CambiarContrasenaUsuarioLDAPConPrivilegios(string dominio, string nombreUsuario, string contrasena, string nuevaContrasena) { try { srvLDAPActiveDirectory = new DirectoryEntry("LDAP://DC=" + dominio + ",DC=" + "com", nombreUsuario, contrasena); if (srvLDAPActiveDirectory != null) { DirectorySearcher searchEntry = new DirectorySearcher(srvLDAPActiveDirectory); searchEntry.Filter = "(samaccountname=" + nombreUsuario + ")"; SearchResult result = searchEntry.FindOne(); if (result != null) { DirectoryEntry userEntry = result.GetDirectoryEntry(); if (userEntry != null) { userEntry.Invoke("SetPassword", new object[] { nuevaContrasena }); userEntry.Properties["lockouttime"].Value = 0; MessageBox.Show("La contraseña se ha cambiado correctamente.", "Contraseña cambiada...", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show("No se ha encontrado el usuario en el servidor LDAP.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } else { MessageBox.Show("No se ha encontrado el usuario en el servidor LDAP.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } else { MessageBox.Show("No se ha podido conectar con el servidor LDAP.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } catch (Exception ex) { MessageBox.Show("No se ha podido cambiar la contraseña: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void btSalir_Click(object sender, EventArgs e) { Application.Exit(); } private void txtContrasenaNueva2_Enter(object sender, EventArgs e) { if (txtContrasenaNueva2.Text != "") txtContrasenaNueva2.SelectAll(); } private void txtContrasenaNueva_Enter(object sender, EventArgs e) { if (txtContrasenaNueva.Text != "") txtContrasenaNueva.SelectAll(); } private void txtContrasenaActual_Enter(object sender, EventArgs e) { if (txtContrasenaActual.Text != "") txtContrasenaActual.SelectAll(); } } } |
La aplicación Resetear/Restablecer contraseña Active Directory en funcionamiento
Para que la aplicación funcione necesitaremos tener instalado .NET Framework 4.7.2 o superior en el equipo. El equipo o equipos donde ejecutaremos la aplicación debe pertenecer al dominio Active Directory de la organización:
Abriremos el ejecutable de la aplicación (incluido en la descarga del código fuente), ResetearContrasenaAD.exe, nos mostrará la siguiente ventana:
Introduciremos los siguientes datos:
- Dominio: nombre del dominio Active Directory en el que tenemos agregado el equipo y en el que tenemos el usuario de inicio de sesión.
- Usuario: nombre del usuario con el que iniciamos sesión en el equipo, validando en el dominio.
- Contraseña actual del usuario anterior.
- Nueva contraseña: introduciremos la nueva contraseña para el usuario anterior.
- Repetiremos la nueva contraseña.
Para cambiar la contraseña por la nueva pulsaremos en «Cambiar contraseña»:
Si todo es correcto, devolverá un mensaje indicando que la contraseña se ha cambiado:
Contraseña cambiada…
La contraseña se ha cambiado correctamente.
Le recomendamos que cierre sesión en el equipo y vuelva a acceder con la nueva contraseña.
Aceptar
Descarga del código fuente completo de la aplicación C# para restablecer la contraseña de un usuario de LDAP Active Directory
La descarga de la solución completa con código fuente en C# (C Sharp), desarrada en Microsoft Visual Studio Community 2019:
Algunos errores al restablecer/cambiar la contraseña de un usuario LDAP Active Directory
A continuación detallamos algunos de los errores que se pueden producir al cambiar la contraseña de un usuario en el dominio Active Directory.
- Error si el usuario actual no existe en el dominio:
Error…
No se ha podido cambiar la contraseña. Se ha producido el siguiente error:
Referencia a objeto no establecida como instancia de un objeto.
Aceptar
- Error si la contraseña del usuario actual no coincide con la del sistema:
Error…
No se ha podido cambiar la contraseña. Se ha producido el siguiente error:
La contraseña de red especificada no es válida. (Excepción de HRESULT: 0x80070056)
Aceptar
- Error si la contraseña nueva que se introduce no cumple con los requisitos de directiva de contraseñas, la complejidad de la contraseña, que habitualmente fuerzan a que la contraseña contenga números y letras (mayúscuas y minúsculas) y algún carácter especial:
Error…
No se ha podido cambiar la contraseña. Se ha producido el siguiente error:
La contraseña no cumple con los requisitos de la directiva de contraseñas. Compruebe los requisitos de longitud mínima, complejidad e historial de la contraseña. (Excepción de HRESULT: 0x800708C5)
Aceptar
- Error si la contraseña nueva que se introduce ya fue usada en otro momento:
Error…
No se ha podido cambiar la contraseña. Se ha producido el siguiente error:
La contraseña no cumple con los requisitos de la directiva de contraseñas. Compruebe los requisitos de longitud mínima, complejidad e historial de la contraseña. (Excepción de HRESULT: 0x800708C5)
Aceptar
- Error si el dominio introducido no existe o no está disponible:
Error…
No se ha podido cambiar la contraseña. Se ha producido el siguiente error:
No fue posible ponerse en contacto con el servidor.
Aceptar