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

40 respuestas a “Autenticación de usuarios usando PHP y Active Directory de Windows Server”

  1. 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

    • Gracias!, Referente a tu consulta, realmente es un tema interesante… SSO (single sign-on) creo. La verdad es que me intereso el tema e investigué mucho al respecto pero al final lo dejé porque no sé si es posible hacerlo con php y active directory. Por ejemplo, Sharepoint!; Una vez te logueas en Windows (dominio) y abres el Internet Explorer (solo con ese funcionaba… por lo menos la versión de sharepoint que probé en su momento) y el sharepoint te identifica con tu usuario de dominio. Exactamente lo que tu quieres. Si abrías firefox en ésa misma sesión de windows, te pedía usuario y contraseña (típico de microsoft). Si se puede con ASP.NET, debería de haber algo en php, me dije, pero al final no lo culminé. Si logras hacerlo, te agradecería mucho que me dieras el dato.

  2. 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

      • Inge… recientente estoy desarrollando un sistema de control de usuarios en php, utilizo el patron de desarollo MVC para una tesis, el caso es el siguiente:

        los usuarios que se loguean en el sistema tiene asignado un perfil de usuario «administrador, reportes, restriccion», de esta manera hay un tabla menús donde se almacenan un menú dinamico que en base al usuario logueado este se lo muestra, tengo una tabla llamada menu_perfil que es donde se registro el id de perfil y el id de menu, como puedo hacer para que el usuario logueado tenga acceso o no al menu que tengo registrado en esta tabla en base a su perfil y el menú asignado?

        espero no haber sido muy confusa mi explicación y me puedan orientar en ello.

  3. 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. 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

  5. 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

  6. 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.

  7. Buenas tardes,

    Tu codigo me sirvio un monton y lo agradezco. necesitaria saber si existe una forma con este mismo codigo, pero de listar todos los usuarios que tengo en el AD, muchas gracias!

  8. Hola Oscar,
    Muy claro tu código, Soy nuevo en PHP, apenas unos dias, pero se entiende a la perfección y funciona. Tengo una pregunta, si podrás orientarme. Según el modelo MVC puse los archivos .php en una subcarpeta, me quedó index.php en el root del proyecto y los demás archivos en la carpeta Controllers. No estoy pudiendo volver a index.php. Muy agradecido si me das una manito con eso.
    Saludos,

  9. Profe le agradezco por este aporte tan grande llevaba días buscando como hacer esto, ahora una pregunta como hago para validar que solo deje ingresar si el usuario que se autentica pertenece a determinado grupo de usuarios de el Directorio Activo. gracias

  10. Buenas, es muy bueno el post.
    Ahora te hago una consulta, es posible hacer que el usuario pueda cambiar su clave?
    Si la clave del usuario caduca, se la dejaria cambiar?

  11. hola buenas tardes por favor me podrías ayudar soy nuevo en ldap y necesito un filtro que me autentique un usuario en grupo llamado ti-funcional que debería cambiar, gracias

  12. Hola, muchas gracias por compartir me ha servido mucho, solo tengo una pregunta, que en la bienvenida en lugar de mostrar el username se podrá traer el nombre completo con apellidos

    • Hola Luis Caicedo, yo tenía la misma pregunta, estoy empezando con PHP y lo resolví del siguiente modo:
      1- Copie el código de Ldap.php dentro de Control.php para no tener que invocar a una función.
      2- Justo debajo donde dice:
      $array = $info[0][«samaccountname»][0];
      Agregué este código:
      $fields = array(«displayname»);
      $sr = @ldap_search($ldapconn, $dn, $filter, $fields);
      $info = @ldap_get_entries($ldapconn, $sr);
      $nombre = $info[0][«displayname»][0];
      3- Finalmente agregué el nombre el usuario al array SESSION:
      $_SESSION[«nombre»] = $nombre;

      Espero que te sirva.
      Saludos,

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*