martes, 25 de agosto de 2009

Usando Forms-based authentication con Active Directory

Usando Forms-based authentication con Active Directory

La autenticación de Forms es un sistema en el que las solicitudes no autenticadas se redirigen a un formulario web donde los usuarios están obligados a proporcionar sus credenciales.


Después de la presentación de la forma, y de ser adecuadamente verificada por su solicitud, un ticket de autorización es expedido por la aplicación Web, en la forma de una cookie. Esta cookie contiene las credenciales de autorización del usuario o una clave para readquirir la identidad del usuario (por lo tanto hacer de la identidad persistente del usuario). En esencia, la autenticación de formularios es un medio para el llenado de la aplicación Web con una fina capa de seguridad, que le permite tener su propia interfaz de inicio de sesión personalizado y funcionalidad de verificación.

Active Directory

Active Directory es un elemento esencial e inseparable de la arquitectura de la red de Windows que permite a las organizaciones compartir y gestionar de manera eficiente la información sobre los recursos de red y los usuarios. Básicamente se trata de un único punto de gestión para Windows basado en cuentas de usuarios, clientes y aplicaciones. También ayuda a las organizaciones a integrar la no aplicación de Windows con aplicaciones basadas en Windows y dispositivos, lo que consolida los directorios y facilitar la gestión de todo el sistema operativo de red. Las organizaciones también utilizan Active Directory para ampliar los sistemas de forma segura a Internet, al obligar a sus usuarios de la aplicación Web para autenticar contra su único punto de Active Directory.

Requisitos

Microsoft Windows
Microsoft ® Visual Studio. NET
Conocimiento de Microsoft Visual C # ™

Antes de empezar

En este artículo voy a mostrar cómo implementar la autenticación de formularios mediante las credenciales de Active Directory. Los formularios de autenticación de ASP.NET permite a los usuarios escriben sus credenciales (nombre de usuario y contraseña) en un formulario web para identificarse. La aplicación Web recibe la credencial, y se puede autenticar al usuario verificar su nombre de usuario y contraseña en un conjunto de datos disponibles. En este artículo se describe cómo autenticar a los usuarios de Microsoft ® Active Directory ® utilizando el protocolo LDAP (Protocolo ligero de acceso a datos). También se describe cómo almacenar esa información en un objeto GenericPrincipal y cómo almacenarlo en la propiedad HttpContext.Current.User que sigue a la petición de lanzar la aplicación Web ASP.NET.

Crear la página de inicio de sesión

Lo primero que tenemos que hacer es crear una nueva solución en Visual Studio 2005. Y añadir un nuevo sitio web. El sitio web debe tener una página de acceso simple, como la que muestran en la imagen siguiente. El objetivo de esta página es como cada página de inicio de sesión, para validar el nombre de usuario y contraseña en un dominio, la diferencia es que el proceso de validación validará en Active Directory.




En el evento de load de la página de acceso puede agregar el siguiente código para mostrar el dominio de la identidad y nombre de usuario asociado con la solicitud Web actual, esto con la finalidad de ayudar al usuario.



if(!Page.IsPostback())
{
string domainUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
string[] paramsLogin = domainUser.Split('\\');
txtUser.Text = paramsLogin[1].ToString();
txtDomain.Text = paramsLogin[0].ToString();
}

Configuración de la aplicación

Ahora tenemos que configurar la aplicación para que admite la autenticación de formularios. Usted puede hacer esto a través del archivo Web.config. Tienes que cambiar el modo de autenticación en el web.config y agregue un elemento secundario para configurar la página de acceso, el tiempo de espera de sesión y el cookie que contiene la información de autenticación.

Además, debe agregar la etiqueta para permitir que sólo los usuarios autenticados, tienen acceso a la aplicación. Si el proceso de inicio de sesión no se realizó correctamente, el usuario será redirigido a la página de inicio de sesión.
Para los que van a virtual de la aplicación de directorio en Propiedades y, a continuación, haga clic en la pestaña de seguridad en el acceso anónimo y el grupo de control de autenticación y desactive la casilla Acceso anónimo.

Después de que se necesita una pequeña modificación en el web.config. Usted tendrá que agregar un elemento debajo del elemento en Web.config y establecer el atributo impersonate en true. Esto hace que ASP.NET para suplantar la cuenta anónima especificada anteriormente.

Así que el archivo de configuración que se parece a éste:

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

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

< identity impersonate="true" / >

Como resultado de esta configuración, cada solicitud dirigida a la aplicación se ejecutará en el contexto de cuenta configurada anónimos de seguridad. El usuario deberá proporcionar credenciales a través del formulario Web para autenticarse en Active Directory, pero la cuenta que se utilizarán para tener acceso a Active Directory será la cuenta configurada de forma anónima

Implementando la validación en active directory

Llego el momento para escribir el código de autenticación del Active Directory. Va a crear una nueva clase que proporcionará un método que recibe un nombre de dominio, nombre de usuario y la contraseña como parámetro y devuelve un valor booleano que indica si existe un registro coincidente en Active Directory.

Vamos crear una Libreria de clases con una clase que implementa un método de autenticación contra AD. Usted tendrá que agregar una referencia al Asembly System.DirectoryServices.dll. Esto proporciona acceso al espacio de nombres System.DirectoryServices que contiene tipos administrados como ayuda en la consulta y el tratamiento en Active Directory.
La conexión a Active Directory es a través de LDAP. Usted tiene que especificar la ruta de conexión. Para el proceso de búsqueda de AD tendrá un atributo de filtro.



Inicialmente, el método intenta conectar con Active Directory utilizando las credenciales proporcionadas. EL método utiliza la clase administrada DirectorySearcher para buscar el objeto de usuario especificado.
Código de la clase:

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

private string _path;
private string _filterAttribute;

public Class LdapAuthentication
{

public LdapAuthentication(string path)
{
_path = path;
}

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;
}

}

Implementando el Proceso de autenticación

En este paso se van a desarrollar plenamente el proceso de autenticación que se pondrá en marcha cuando el usuario hace clic en el botón de inicio de sesión utilizando la clase construida antes.

Para los usuarios autenticados, la autenticación de form-base será creada y el usuario será redirigido a la página original que había pedido.
Ahora abría de agregar en el botón de inicio de sesión un event handler con código que cree una nueva instancia de la clase de validación del Active Directory. El proceso de autenticación tiene que realizar los siguientes pasos:

a. Autenticar al usuario contra el Active Directory.
b. crear una credencial de FormsAuthenticationTicket que identifica al usuario.
c. Encriptar la credencial.
d. Crear una nueva cookie que contiene el Ticket.
e. Agregue la cookie a la lista de las cookies que se devuelven al explorador del usuario.

// Path to you LDAP directory server.
// Contact your network administrator to obtain a valid path.
string adPath = "LDAP://localhost;
LdapAuthentication adAuth = new LdapAuthentication(adPath);


try
{
if(true == adAuth.IsAuthenticated(txtDomainName.Text, txtUserName.Text,txtPassword.Text))
{
// 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));
}
else
{
lblError.Text = ”Authentication failed, check username and password.";
}
}
catch (Exception ex)
{
lblError.Text = "Error authenticating. " + ex.Message;
}

Recuerde que debe cambiar la ruta de acceso de modo que tiene como objetivo el AD Server, y el nombre de la cookie debe ser el mismo nombre que hemos especificado en el archivo Web.config.

Implementando la solicitud de autenticación

Ahora la pregunta es cómo la aplicación sabe si el usuario está autenticado o no cada vez que la aplicación realiza una solicitud.

Se puede hacer este procedimiento en el archivo Global.asax. que tiene que implementar un evento denominado Application_AuthenticateRequest. Recuerde que en los pasos anteriores se genera una cookie de con un un Ticket de autenticación. En este evento debe extraer información de las cookies y crea un objeto GenericPrincipal de identificar al usuario autenticado.

Por último, el objeto GenericPrincipal se asociará con el objeto HttpContext actual crea para cada solicitud Web.

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

// Extract the forms authentication cookie
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
if(null == authCookie)
{
// There is no authentication cookie.
return;
}

FormsAuthenticationTicket authTicket = null;
Try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch (Exception ex)
{
// Log exception details (omitted for simplicity)
return;
}
if (null == authTicket)
{
// Cookie failed to decrypt.
return;
}

// Create an Identity object
GenericIdentity id = new GenericIdentity(authTicket.Name,"LdapAuthentication");

// This principal will flow throughout the request.
GenericPrincipal principal = new GenericPrincipal(id, null);

// Attach the new principal object to the current HttpContext object
Context.User = principal;

Probando la Aplicación
Ya terminado el proceso de autenticación y es hora de probarlo. Introduzca un nombre de dominio válido, nombre de usuario y contraseña y haga clic en Iniciar sesión, si está autenticado correctamente, debería ser enviado de nuevo a la página que establece como valor predeterminado. Si intenta cambiar la URL manualmente antes de inicio de sesión, obtendrá el mismo resultado que un inicio de sesión no válida, la solicitud se tenga en cuenta que no hay ningún usuario autenticado por lo que será redirigido a la página inicio de sesión de nuevo.

Articulos relacionados

How To: Use Forms Authentication with Active Directory in ASP.NET 2.0
http://msdn.microsoft.com/en-us/library/ms998360.aspx
System.DirectoryServices Namespace
http://msdn.microsoft.com/en-us/library/system.directoryservices.aspx
http://www.15seconds.com/issue/050203.htm
http://www.beansoftware.com/ASP.NET-Tutorials/Forms-Authentication-Active-Directory.aspx
Personas participantes en el artículo:
Luis Oswaldo Gonzales
Carlos Juan Orellana

2 comentarios:

Anónimo dijo...

Gracias, me sirvio fue muy util? =)=)=)=)=)=) !!!!

Anónimo dijo...

El material esta bien, pero tu ejemplo tiene demasiados errores de codigo, seria preferible que pusieras la demo para descargarla, asi almenos podrias evitar ciertos errores...

Saludos..!!

Enrique Aylas R.