You are on page 1of 10

Utilizar la autenticación mediante Formularios con

Active Directory
La autenticación mediante Formularios de ASP.NET permite que los usuarios escriban
sus credenciales (nombre de usuario y contraseña) en un formulario Web para
identificarse. Al recibir las credenciales, la aplicación Web puede autenticar al usuario
mediante la comprobación del nombre de usuario y de su contraseña en un conjunto de
datos disponible.
En este artículo se describe cómo autenticar usuarios en el servicio de directorio
Microsoft® Active Directory® mediante el Protocolo ligero de acceso a directorios
(LDAP). También se describe cómo recuperar una lista de grupos de seguridad y listas
de distribución a los que pertenece el usuario, cómo almacenar esa información en un
objeto GenericPrincipal y cómo almacenarla en la propiedad
HttpContext.Current.User que acompaña a la solicitud a través de la aplicación Web
ASP.NET. Posteriormente se puede utilizar para la autorización basada en funciones de
.NET.

Requisitos
A continuación se describen las recomendaciones de hardware, software, infraestructura
de red, conocimientos y Service Pack que se necesitan.
Sistema operativo Microsoft Windows® 2000
Sistema de desarrollo Microsoft Visual Studio® .NET

Para llevar a cabo los procedimientos de este artículo, también es necesario que tenga
conocimientos de la herramienta de desarrollo Microsoft Visual C#™.

Resumen
En este artículo se incluyen los siguientes procedimientos:
1. Crear una aplicación Web con una página de inicio de sesión
2. Configurar la aplicación Web para la autenticación mediante Formularios
3. Desarrollar código de autenticación LDAP para buscar el usuario en Active
Directory
4. Desarrollar código LDAP de recuperación de grupos para consultar la pertenencia
a grupos del usuario
5. Autenticar al usuario y crear un vale de autenticación mediante Formularios
6. Implementar un controlador de solicitudes de autenticación para construir un
objeto GenericPrincipal
7. Probar la aplicación

1
1. Crear una aplicación Web con una página de inicio de
sesión
En este procedimiento se crea una sencilla aplicación Web en C#, la cual contiene una
página de inicio de sesión que permite a los usuarios escribir un nombre de usuario y
una contraseña, y una página predeterminada que muestra el nombre de la identidad e
información de pertenencia a grupos asociada a la solicitud Web actual.
Para crear una aplicación Web con una página de inicio de sesión
1. Inicie Visual Studio .NET y cree una nueva aplicación Web ASP.NET en C# con el
nombre FormsAuthAD.
2. Utilice el Explorador de soluciones para cambiar el nombre de WebForm1.aspx
por Logon.aspx.
3. Agregue una nueva referencia de ensamblado a System.DirectoryServices.dll.
Esto proporciona acceso al espacio de nombres System.DirectoryServices que
contiene tipos administrados como ayuda en la consulta y tratamiento en Active
Directory.
4. Agregue a Logon.aspx los controles que se enumeran en la tabla 1 para crear un
sencillo formulario de inicio de sesión.
Tabla 1: Controles de Logon.aspx

Tipo de control Texto Id.


Etiqueta Domain Name: -
Etiqueta User Name: -
Etiqueta Password -
Cuadro de texto - txtDomainName
Cuadro de texto - txtUserName
Cuadro de texto - txtPassword
Botón Log On btnLogon
Etiqueta lblError

5. Establezca el valor Password en la propiedad TextMode de txtPassword.


6. En el Explorador de soluciones, haga clic con el botón secundario del mouse
(ratón) en FormsAuthAd, seleccione Agregar y, después, haga clic en Agregar
formulario Web.
7. En el campo Nombre, escriba default.aspx y, a continuación, haga clic en Abrir.
8. En el Explorador de soluciones, haga clic con el botón secundario en default.aspx
y, a continuación, haga clic en Establecer como página de inicio.
9. Haga doble clic en default.aspx para mostrar el controlador de eventos de carga
de la página.
10. Agregue el siguiente código al controlador de eventos para mostrar el nombre de
identidad asociado a la solicitud Web actual.

Response.Write( HttpContext.Current.User.Identity.Name );

2
2. Configurar la aplicación Web para la autenticación
mediante Formularios
En este procedimiento se modifica el archivo Web.config de la aplicación para
configurarla de forma que admita la autenticación mediante Formularios.
Para configurar la aplicación Web para la autenticación mediante Formularios
1. Utilice el Explorador de soluciones para abrir Web.config.
2. Busque el elemento <authentication> y cambie el atributo mode a Forms.
3. Agregue el elemento <forms> siguiente como elemento secundario del elemento
de autenticación y configure los atributos loginUrl, name, timeout y path como se
muestra a continuación.

<authentication mode="Forms">
<forms loginUrl="logon.aspx" name="adAuthCookie" timeout="60" path="/">
</forms>
</authentication>

4. Agregue el siguiente elemento <authorization> debajo del elemento


<authentication>. Esto permitirá que sólo los usuarios autenticados tengan
acceso a la aplicación. El atributo loginUrl del elemento <authentication>
establecido anteriormente redirigirá las solicitudes no autenticadas a la página
logon.aspx.

<authorization>
<deny users="?" />
<allow users="*" />
</authorization>

5. Guarde Web.config.
6. Inicie el complemento Microsoft Management Console (MMC) de IIS.
7. Haga clic con el botón secundario en el directorio virtual de la aplicación y,
después, haga clic en Propiedades.
8. Haga clic en la ficha Seguridad de directorios y, después, en el botón Modificar
del grupo Acceso anónimo y control de autenticación.
9. Active la casilla de verificación Acceso anónimo y desactive la casilla Permitir
que IIS controle las contraseñas.
10. Puesto que la cuenta anónima predeterminada IUSR_MACHINE no cuenta con
permiso para tener acceso a Active Directory, cree una nueva cuenta con
privilegios mínimos y especifique los detalles de la cuenta en el cuadro de diálogo
Métodos de autenticación.
11. Haga clic en Aceptar y, a continuación, de nuevo en Aceptar para cerrar el
cuadro de diálogo Propiedades.
12. Vuelva a Visual Studio .NET y agregue un elemento <identity> debajo del
elemento <authorization> en Web.config, y configure el atributo de suplantación
en true. De esta manera, ASP.NET suplantará la cuenta anónima especificada
anteriormente.

<identity impersonate="true" />

3
Como resultado de esta configuración, todas las solicitudes dirigidas a la
aplicación se ejecutarán en el contexto de seguridad de la cuenta anónima
configurada. El usuario proporcionará credenciales a través del formulario Web
para autenticarse en Active Directory, pero la cuenta que se utilizará para tener
acceso a Active Directory será la cuenta anónima configurada.

3. Desarrollar código de autenticación LDAP para buscar el


usuario en Active Directory
En este procedimiento se agrega una nueva clase auxiliar a la aplicación Web para
encapsular el código LDAP. La clase proporcionará inicialmente un método
IsAuthenticated para validar un dominio, un nombre de usuario y una contraseña
suministrados con un objeto de usuario de Active Directory.
Para desarrollar código de autenticación LDAP para buscar el usuario en
Active Directory
1. Agregue un nuevo archivo de clase de C# con el nombre LdapAuthentication.cs.
2. Agregue una referencia al ensamblado System.DirectoryServices.dll.
3. Agregue las siguientes instrucciones using al principio del archivo
LdapAuthentication.cs.

using System.Text;
using System.Collections;
using System.DirectoryServices;

4. Cambie el nombre del espacio de nombres existente a FormsAuthAD.


5. Agregue dos cadenas privadas a la clase LdapAuthentication: una para contener
la ruta de acceso LDAP de Active Directory y la otra para contener un atributo de
filtro utilizado para buscar en Active Directory.

private string _path;


private string _filterAttribute;

6. Agregue un constructor público que se pueda utilizar para inicializar la ruta de


acceso de Active Directory.

public LdapAuthentication(string path)


{
_path = path;
}

7. Agregue el siguiente método IsAuthenticated que acepta un nombre de dominio,


un nombre de usuario y una contraseña como parámetros, y que devuelve un
valor de tipo bool para indicar si el usuario que tiene una contraseña coincidente
existe en Active Directory. Inicialmente, el método intenta enlazar con Active
Directory mediante las credenciales suministradas. Si tiene éxito, el método utiliza
la clase administrada DirectorySearcher para buscar el objeto de usuario
especificado. Si se encuentra, el miembro _path se actualiza para que apunte al
objeto de usuario y el miembro _filterAttribute se actualiza con el atributo de
nombre común del objeto de usuario.

4
public bool IsAuthenticated(string domain, string username, string pwd)
{
string domainAndUsername = domain + @"\" + username;
DirectoryEntry entry = new DirectoryEntry( _path,
domainAndUsername, pwd);

try
{
// Bind to the native AdsObject to force authentication.
Object obj = entry.NativeObject;
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(SAMAccountName=" + username + ")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
if(null == result)
{
return false;
}
// Update the new path to the user in the directory
_path = result.Path;
_filterAttribute = (String)result.Properties["cn"][0];
}
catch (Exception ex)
{
throw new Exception("Error authenticating user. " + ex.Message);
}
return true;
}

4. Desarrollar código LDAP de recuperación de grupos


para consultar la pertenencia a grupos del usuario
En este procedimiento se amplía la clase LdapAuthentication para proporcionar un
método GetGroups que recuperará la lista de grupos de los que es miembro el usuario
actual. El método GetGroups devolverá la lista de grupos como una cadena, donde
cada grupo vendría delimitado por el carácter |, como se indica a continuación.

"Group1|Group2|Group3|"

Para desarrollar código LDAP de recuperación de grupos para consultar la


pertenencia a grupos del usuario
1. Agregue la siguiente implementación del método GetGroups a la clase
LdapAuthentication.

public string GetGroups()


{
DirectorySearcher search = new DirectorySearcher(_path);
search.Filter = "(cn=" + _filterAttribute + ")";
search.PropertiesToLoad.Add("memberOf");

5
StringBuilder groupNames = new StringBuilder();
try
{
SearchResult result = search.FindOne();
int propertyCount = result.Properties["memberOf"].Count;
String dn;
int equalsIndex, commaIndex;

for( int propertyCounter = 0; propertyCounter < propertyCount;


propertyCounter++)
{
dn = (String)result.Properties["memberOf"][propertyCounter];

equalsIndex = dn.IndexOf("=", 1);


commaIndex = dn.IndexOf(",", 1);
if (-1 == equalsIndex)
{
return null;
}
groupNames.Append(dn.Substring((equalsIndex + 1),
(commaIndex - equalsIndex) - 1));
groupNames.Append("|");
}
}
catch (Exception ex)
{
throw new Exception("Error obtaining group names. " + ex.Message);
}
return groupNames.ToString();
}

5. Autenticar al usuario y crear un vale de autenticación


mediante Formularios
En este procedimiento se implementa el controlador de eventos btnLogon_Click para
autenticar a los usuarios. Para los usuarios autenticados, se creará después un vale de
autenticación mediante Formularios que contenga la lista de grupos del usuario. A
continuación se redirigirá al usuario a la página original que solicitó (antes de la
redirección a la página de inicio de sesión).
Para autenticar al usuario y crear un vale de autenticación mediante
Formularios
1. Vuelva al formulario Logon.aspx y haga doble clic en el botón Log On para crear
un controlador de eventos vacío con el nombre btnLogon_Click.
2. Al principio del archivo, agregue la siguiente instrucción using debajo de las
instrucciones using existentes. De esta manera se proporciona acceso a los
métodos FormsAuthentication.

using System.Web.Security;

6
3. Agregue código para crear una nueva instancia de la clase LdapAuthentication
inicializada de forma que apunte a Active Directory en el servidor LDAP, como se
muestra en el código siguiente. Recuerde que debe cambiar la ruta de acceso
para que apunte al servidor de Active Directory.

// Path to you LDAP directory server.


// Contact your network administrator to obtain a valid path.
string adPath = "LDAP://yourCompanyName.com/DC=yourCompanyName,DC=com";
LdapAuthentication adAuth = new LdapAuthentication(adPath);

4. Agregue el código que se incluye a continuación para realizar los siguientes


pasos:
a. Autenticar al llamador con Active Directory.
b. Recuperar la lista de grupos de los que el usuario es miembro.
c. Crear un vale FormsAuthenticationTicket que contenga la lista de grupos.
d. Cifrar el vale.
e. Crear una cookie nueva que contenga el vale cifrado.
f. Agregar la cookie a la lista de cookies que se devuelven al explorador del
usuario.

try
{
if(true == adAuth.IsAuthenticated(txtDomainName.Text,
txtUserName.Text,
txtPassword.Text))
{
// Retrieve the user's groups
string groups = adAuth.GetGroups();
// Create the authetication ticket
FormsAuthenticationTicket authTicket =
new FormsAuthenticationTicket(1, // version
txtUserName.Text,
DateTime.Now,
DateTime.Now.AddMinutes(60),
false, groups);
// Now encrypt the ticket.
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
// Create a cookie and add the encrypted ticket to the
// cookie as data.
HttpCookie authCookie =
new HttpCookie(FormsAuthentication.FormsCookieName,
encryptedTicket);
// Add the cookie to the outgoing cookies collection.
Response.Cookies.Add(authCookie);

// Redirect the user to the originally requested page


Response.Redirect(
FormsAuthentication.GetRedirectUrl(txtUserName.Text,
false));

7
}
else
{
lblError.Text =
"Authentication failed, check username and password.";
}
}
catch (Exception ex)
{
lblError.Text = "Error authenticating. " + ex.Message;
}

6. Implementar un controlador de solicitudes de


autenticación para construir un objeto GenericPrincipal
En este procedimiento se implementa el controlador de eventos
Application_AuthenticateRequest en global.asax y se crea un objeto
GenericPrincipal para el usuario autenticado actualmente. Contendrá la lista de grupos
de los que es miembro el usuario, recuperada en el vale FormsAuthenticationTicket
contenido en la cookie de autenticación. Por último, se asociará el objeto
GenericPrincipal con el objeto HttpContext actual que se crea para cada solicitud Web.
Para implementar un controlador de solicitudes de autenticación para
construir un objeto GenericPrincipal
1. Utilice el Explorador de soluciones para abrir global.asax.cs.
2. Agregue las siguientes instrucciones using al principio del archivo.

using System.Web.Security;
using System.Security.Principal;

3. Busque el controlador de eventos Application_AuthenticateRequest y agregue


el siguiente código para obtener la cookie que contiene el vale
FormsAuthenticationTicket cifrado en la colección de cookies pasada con la
solicitud.

// Extract the forms authentication cookie


string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];

if(null == authCookie)
{
// There is no authentication cookie.
return;
}

4. Agregue el siguiente código para extraer el vale FormsAuthenticationTicket de


la cookie y descifrarlo.

FormsAuthenticationTicket authTicket = null;


try

8
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch (Exception ex)
{
// Log exception details (omitted for simplicity)
return;
}

if (null == authTicket)
{
// Cookie failed to decrypt.
return;
}

5. Agregue el siguiente código para analizar la lista de nombres de grupos separados


por el símbolo | que se adjuntó al vale cuando el usuario se autenticó
originalmente.

// When the ticket was created, the UserData property was assigned a
// pipe delimited string of group names.
String[] groups = authTicket.UserData.Split(new char[]{'|'});

6. Agregue el siguiente código para crear un objeto GenericIdentity con el nombre


de usuario obtenido en el nombre del vale y un objeto GenericPrincipal que
contenga esa identidad junto con la lista de grupos del usuario.

// Create an Identity object


GenericIdentity id = new GenericIdentity(authTicket.Name,
"LdapAuthentication");

// This principal will flow throughout the request.


GenericPrincipal principal = new GenericPrincipal(id, groups);
// Attach the new principal object to the current HttpContext object
Context.User = principal;

7. Probar la aplicación
En este procedimiento se utiliza la aplicación Web para solicitar la página default.aspx.
Se le redirigirá a la página de inicio de sesión para llevar a cabo la autenticación. Una
vez realizada correctamente la autenticación, se redirigirá el explorador a la página
default.aspx solicitada originalmente. De esta forma se extraerá y mostrará la lista de
grupos a los que pertenece el usuario autenticado del objeto GenericPrincipal que se
ha asociado a la solicitud actual en el proceso de autenticación.
Para probar la aplicación
1. En el menú Generar, haga clic en Generar solución.
2. En el Explorador de soluciones, haga clic con el botón secundario en default.aspx
y, a continuación, haga clic en Ver en el explorador.

9
3. Escriba un nombre de dominio (Domain Name), un nombre de usuario (User
Name) y una contraseña (Password) válidos y, después, haga clic en Log on
(Iniciar sesión).
4. Si se autentica correctamente, debe producirse de nuevo la redirección a
default.aspx. El código de esta página debe mostrar el nombre de usuario del
usuario autenticado.
Para ver la lista de grupos de los que es miembro el usuario autenticado, agregue
el siguiente código al final del controlador de eventos
Application_AuthenticateRequest en el archivo global.aspx.cs.

Response.Write("Groups: " + authTicket.UserData + "<br>");

10

You might also like