Print Shortlink

Autenticación de usuarios usando PHP y Active Directory de Windows Server

En un post anterior titulado Control de sesiones – Autenticación de usuarios usando PHP y MySQL, se habló referente a cómo realizar un inicio de sesión que se autentique contra un tabla de usuarios en mysql y éste cree una sesión para éste usuario, de tal manera que nuestra aplicación esté protegida mediante ésta sesión y, cuando el usuario se salga del aplicativo web, se destruya la sesión. Bien, en ésta entrada veremos otra opción de autenticación; en lugar de una tabla en mysql, podemos usar Active Directory de un Windows Server (probado con versión 2000, 2003, 2008 y 2012). Si desean saber cómo gestionar los usuarios, ver la entrada: Uso básico de Active Directory – Windows Server.

Bien, un poco de teoría:

¿Qué es Active Directory? Implementación de un servicio de directorio en una red distribuida de computadores; almacena y organiza la información sobre los usuarios de una red de computadoras, sobre recursos de red, y permite a los administradores gestionar el acceso de usuarios a los recursos sobre dicha red.

Yo lo veo (puntualmente hablando) como una base de datos de usuarios, grupos de usuarios, computadoras, etc. de tal manera nos pueda servir para centralizar la autenticación de los usuarios y aplicar políticas a nivel de dominio.

Ahora, a lo que venimos… El requisito que necesitamos es que nuestra instalación PHP tenga la extensión o librerías que soporte LDAP. Como soy bastante “Linuxero”, éste tutorial va enfocado para Ubuntu, pero para Windows es la misma lógica. Para los que tengan duda de PHP… Se recuerdan de la tecnología LAMP?

Instalando ldap en php. Nos vamos a una terminal y digitamos:

sudo apt-get install php5-ldap

Esto nos instalará la extensión de php necesaria para poder conectarnos a un servidor ldap (en nuestro caso, un Active Directory!). En Windows, hay que descomentariar la extensión de ldap, o sea “extension = php_ldap.dll” y la DLL (dependiendo de qué se usa… si XAMPP, AppServ, etc.) debería de tener la dll o igual.. hay que buscarla, copiarla en el lugar de las extensiones de php y reiniciar apache.

Para ver que ya esta funcionando, solo se crean un archivito en su carpeta de publicaciones (/var/www/html) con un nombre y extensión php (info.php por ejemplo) y adentro le ponen:    <?php phpinfo(); ?>

Al ver en el navegador (http://localhost/info.php) deberían de encontrar un apartado LDAP

Ahora, vamos con la programación 😀

NOTA!!!: En éste código me enfocaré netamente en la conexión LDAP, NO estoy tocando temas como la seguridad, validación de campos, estética, etc.

1. Creamos nuestro archivo index.php y lo colocamos en la carpeta donde publicamos nuestro sitio. Al archivo index.php le colocamos el siguiente código.

<?php @session_start(); ?>
    <html>
    <head>
    <title>Acceso por LDAP</title>
    <body>
    <form method="post" action="control.php"><br>
        <table>
            <tr>
                <td>Usuario:</td>
                <td><input type="text" maxlength="50" name="usuario" id="usuario" /></td>
            </tr>
            <tr>
                <td>Clave:</td>
                <td><input type="password" maxlength="50" name="clave" id="clave" />
                </td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="Entrar"></td>
            </tr>
        </table><br>
        </form>
    </body>
    </html>
<?php exit(); ?>

Como pueden ver, es nuestra página inicio donde solicitamos el típico usuario y contraseña. Creo que no hay mucho que explicar… es casi HTML puro, solo hay un pequeño código php que hace referencia a la creación o reanudación de una sesión.

2. Ahora, crearemos nuestro archivo control.php el cual nos servirá para poder realizar el control de la autenticación. Tecleamos lo siguiente:

<?php 
        require("ldap.php"); 
        header("Content-Type: text/html; charset=utf-8"); 
        $usr = $_POST["usuario"]; 
        $usuario = mailboxpowerloginrd($usr,$_POST["clave"]); 
        if($usuario == "0" || $usuario == ''){ 
            $_SERVER = array(); 
            $_SESSION = array(); 
            echo"<script> alert('Usuario o clave incorrecta. Vuelva a digitarlos por favor.'); window.location.href='index.php'; </script>"; 
        }else{ 
            session_start(); 
            $_SESSION["user"] = $usuario; 
            $_SESSION["autentica"] = "SIP"; 
            echo"<script>window.location.href='app.php'; </script>"; 
        } 
?>

Como se puede ver en el código, incluímos un archivo llamado ldap.php, que es el que hace la conexión hacia Active Directory. Luego capturamos el nombre de usuario y la clave (que vienen del Index.php por POST) y hacemos referencia a una función que esta en ldap.php para poder verificar que el usuario y contraseña enviados concuerda con la información en el AD. Luego, se verifica si retorna la función un 0 (no se logró autenticar) o un 1 (si se logró autenticar), para así guardar las variables de sesión respectivas o no. Al final, se redirecciona a la página respectiva dependiendo del resultado de la autenticación.

3. Veamos entonces el código del archivo ldap.php

<?php 
require_once("config.php"); 
function mailboxpowerloginrd($user,$pass){ 
     $ldaprdn = trim($user).'@'.DOMINIO;  
     $ldappass = trim($pass);  
     $ds = DOMINIO;  
     $dn = DN;   
     $puertoldap = 389;  
     $ldapconn = ldap_connect($ds,$puertoldap); 
       ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION,3);  
       ldap_set_option($ldapconn, LDAP_OPT_REFERRALS,0);  
       $ldapbind = @ldap_bind($ldapconn, $ldaprdn, $ldappass);  
       if ($ldapbind){ 
         $filter="(|(SAMAccountName=".trim($user)."))"; 
         $fields = array("SAMAccountName");  
         $sr = @ldap_search($ldapconn, $dn, $filter, $fields);  
         $info = @ldap_get_entries($ldapconn, $sr);  
         $array = $info[0]["samaccountname"][0]; 
       }else{  
             $array=0; 
       }  
     ldap_close($ldapconn);  
     return $array; 
}  
?>

Lo primero que se hace es incluir un archivo de configuración en donde tenemos nuestras constantes, por ejemplo el nombre de dominio y DN. Luego, lo demás del código es para verificar si el usuario y la clave concuerdan con las del Active Directory.

4. El archivo config.php que tiene las constantes de nuestro dominio, contiene el siguiente código:

<?php
    define('DOMINIO', 'midominio.com.sv');
    define('DN', 'dc=midominio,dc=com,dc=sv');
?>

Obviamente, el servidor web debería estar en la misma red donde esta el dominio para que pueda llegar a él mediante su registro DNS. OJO!, deberán de cambiar el nombre de dominio (midominio.com.sv) por el de ustedes. Si en control.php se determina que el usuario y contraseña ingresado corresponde al usuario y contraseña que se encuentra en el Active Directory, redirecciona hacia un archivo app.php el cual es nuestra primera página de nuestra aplicación.

5. Veamos el contenido básico del archivo app.php

<?php include("seguridad.php"); ?>
    <html>
    <head>
        <title>Bienvenido al sistema</title>
    </head>
    <body>
        Hola! <?php echo $_SESSION["user"]; ?><br>
        <br>
        <a href="salir.php">Salir del sistema</a>
    </body>
    </html>

Ésta es la página de bienvenida a nuestra aplicación. Muestra el nombre de usuario logueado y el link para cerrar la sesión. La primera línea hace una inclusión de un archivo seguridad.php el cuál es sumamente importante que se incluya en todas las páginas del sistema que se quiera proteger (que requiera autenticación).

6. Entonces veamos el contenido de seguridad.php

<?php
@session_start();
if($_SESSION["autentica"] != "SIP"){
    header("Location: index.php");
    exit();
}
?>

Aquí validamos si realmente el usuario que quiere acceder a ésta página esta autenticado. Si no lo esta, lo direccionamos a la página index.php. Si esta autenticado, verá la página de bienvenida y su nombre de usuario.

7. Finalmente, en app.php vemos que hay un link hacia un archivo salir.php por lo que veamos el código:

<?php 
 session_start(); 
 session_destroy(); 
 header("Location:index.php"); 
?>

Básicamente se destruye la sesión y direccionamos a index.php. Si el usuario desea nuevamente entrar a app.php, no podrá dado que deberá de autenticarse.

Veamos entonces unas capturas de su funcionamiento:

Inicio de sesión:

Usuario o contraseña inválida:

Autenticación correcta y primera página del sistema:

 

Para las dudas, les dejo adjunto el código fuente de ésta mini aplicación.

[DESCARGAR FUENTES]

Espero que le sirva a alguien. Saludos!

Uso básico de Active Directory – Windows Server

Comentarios por Facebook

comentarios

26 Responses

  1. Miguel

    Hola Oscar, muy claro y practico tu codigo, se comprende super bien.
    Solo tengo una consulta, como puedo hacer para que el usuario y password sea leido de la sesion de windows y no tener que tipearlo? como capturo esos datos? ya que asi lo envio automaticamente para q se valide con el LDAP.
    Gracias de antemano

  2. Harol Cardoza

    Excelete post, es lo que andaba buscando hace varios días… se comprende a la perfección, esta semana lo intentaré implementar con el AD de la empresa.

    Muchas gracias por este tipo de artículos, son de mucha utiidad!

    Saludos

  3. Jonathan

    Buenos Días

    muy buen post, quería preguntar como puedo grabar el usuario y la ip en una tabla de mi base de datos cuando se genere una transacción?

    Gracias

    Gracias

  4. Arney

    Me da error , el ejemplo dice que no sabe quién es el método ldap_connect($ds,$puertoldap);
    que me sugieren , gracias

    1. Boris

      Arney instala LDAP, en centos es yum install php-ldap y reinicia el apache!

  5. Wilson Castellanos

    Buen día

    Muy claro la explicación, hizo autenticación perfecta con directorio activo de windows 2008

    Muchas gracias

  6. jose luis sablon

    Muy bueno y limpio tu ejemplo, muchas gracias

  7. jair

    hola, muy bien explicado ; tengo una consulta he aplicado todo el codigo en mi proyecto y me resulta bien al probarlo en mi local pero cuando lo subo a un servidor e ingresar los mismos datos me sale el mensaje de usuario o clave incorrecta por favor ayudame con ese problema gracias

  8. henry

    buenas tardes, me gustaria saber si es posible al logear un usuario obtener datos del mismo como unidad organizativa sus nombres completos entre otros…

    Gracias

  9. Mlozano

    si quiero hacer una búsqueda de un grupo de usuarios para darles un determinado de perfil según su grupo como seria.?

  10. Boris

    Oscar
    Gracias por tu código… 🙂 me aclaro varias dudas!!

  11. Ivan

    Gracias hermano. Que buen manual!. Una consulta, ¿Cómo puedo jalar datos del Active Directory de un usuario específico y enviarlos a un formulario HTML? Por favor hermano, Gracias

  12. Hector

    Gracias De Verdad Tu Post me Sirvio muchisimo!!!! Espero poder Ayudar de la misma manera a los demas en un futuro, cuando adquiera mas conocimientos.

  13. Carlos

    Hola buenos días, se puede que en lugar del usuario te muestre el campo del nombre completo de AD?

    Saludos y gracias por tu ejemplo.

  14. Mauricio

    Una excelente aportación, me esta haciendo muy útil.

  15. david

    Gracias oscar.

Leave a Reply