ASP.NET + IIS + Active Directory

Hola, a continuacion entregare una demo de como hacer que tu aplicacion web se pueda integrar con Active Directory( o Directorio Activo) si se encuentran dentro de un dominio. es Importante recalcar que ahcemos uso del Espacio del Nombres: DirectoryServices

Primero: Debemos tener en cuenta que para lograr esto , tenemos que ajustar nuestro IIS , dado que es atravez del IIS , nuestra aplicacion web podra conectarse con el Active Directory.

Ojo al piojo:

Para acceder al IIS , Panel de Control->Herramientas Administrativas-> Servicios de Internet Information Server (IIS) o via Windows “Ejercutar” -> inetmgr

iis

Observemos la Imagen:

1.- Hacer click derecho , Propiedades , sobre localhost(en mi caso) ó sobre su IP , o el nombre que tengan en su IIS Local, una vez en las propiedades

2.- En la Pestaña Seguridad de Directorios , DESHABILITAR Acceso Anonimo y Chekar (si estuviese deshabiltada)en el CheckBox “Autenticacion de texto implicita para servidores de dominio Windows”

3.- Chekar “Autenticacion de Windows Integrada” y buscar nuestro dominio o territorio , Aceptar y Listo , OJO ,asegurarse que estamos trabajando con ASP.NET , con el framework 2.0

image

Ahora , crear nuestra Aplicacion Web , Ojo “Aplicacion Web” , no WEB SITE , recordemos que el SP1 del VS2005 permite crear aplicacion web , esto es importante dado que si creamos un web site , nuestro Servidor sera el mini servidor que viene con el vs2005 , creo que es WebServer , ahora si creamos una aplicacion web , nuestro servidor sera el IIS , y eso es importante , pq asi con IIS podremos conectarnos al Active Directory

Nuestro Proyecto:

image

Nuestra Pantalla de Logeo

image

Una vez creada nuestra aplicacion, crear una web form con diseño simple como el que esta en pantalla

En Nuestro web.config.

<?xml version=”1.0″ encoding=”utf-8″?>
<configuration>
  <system.web>
    <authentication mode=”Forms”>
      <forms loginUrl=”logon.aspx” name=”adAuthCookie” timeout=”10″ path=”/”>
      </forms>
    </authentication>
    <authorization>
      <deny users=”?”/>
      <allow users=”*”/>
    </authorization>
    <identity impersonate=”true”/>
  </system.web>
</configuration>

Recordemos que “logon.aspx” , es nuestra pagina de logeo

Creamos una clase de nombre “LdapAuthentication.cs” , Muy Impornte Importar el Espacio de Nombre “System.DirectoryServices”

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

namespace webapp
{
    public class LdapAuthentication
    {
        private string _path;
        private string _filterAttribute;

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

        public string GetGroups()
        {
            DirectorySearcher search = new DirectorySearcher(_path);
            search.Filter = “(cn=” + _filterAttribute + “)”;
            search.PropertiesToLoad.Add(“memberOf”);
            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();
        }
    }
}

En Nuestro evento Click del Boton Login:

protected void Login_Click(object sender, EventArgs e)
        {
            string adPath = “LDAP://(TUDOMINIO).com/DC=(TUDOMINIO),DC=com”;
            LdapAuthentication adAuth = new LdapAuthentication(adPath);
            try
            {
                if (true == adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text))
                {
                    string groups = adAuth.GetGroups();                   
                    bool isCookiePersistent = chkPersist.Checked;
                    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1,
                              txtUsername.Text, DateTime.Now, DateTime.Now.AddMinutes(60), isCookiePersistent, groups);                   
                    string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
                    HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);

                    if (true == isCookiePersistent)
                        authCookie.Expires = authTicket.Expiration;                   
                    Response.Cookies.Add(authCookie);                  
                    Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, false));
                }
                else
                {
                    errorLabel.Text = “No Logeado”;
                }
            }
            catch (Exception ex)
            {
                errorLabel.Text = “Error de Logeo” + ex.Message;
            }
        }

En Nuestro Archivo Global.asax,. Importante los espacios de Nombres:

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

     void Application_AuthenticateRequest(object sender, EventArgs e)
       {
           string cookieName = FormsAuthentication.FormsCookieName;
           HttpCookie authCookie = Context.Request.Cookies[cookieName];

           if (null == authCookie)
           {
                             return;
           }
           FormsAuthenticationTicket authTicket = null;
           try
           {
               authTicket = FormsAuthentication.Decrypt(authCookie.Value);
           }
           catch (Exception ex)
           {
                             return;
           }
           if (null == authTicket)
           {

                           return;
           }
           string[] groups = authTicket.UserData.Split(new char[] { ‘|’ });
           GenericIdentity id = new GenericIdentity(authTicket.Name, “LdapAuthentication”);
           GenericPrincipal principal = new GenericPrincipal(id, groups);
           Context.User = principal;
       }

Finalmente , en nuestra aspx , default.aspx, anadimos una etiqueta “lblUsuario” que nos imprime el usuario registrado

this.lblUsuario.Text = User.Identity.Name;

Ya esta Listo , pruebala con tu dominio.

Jose Fabricio Rojas

DESCARGATE LA DEMO


Acerca de esta Entrada