articulo_ldap

41
Acceso a OpenLDAP mediante Netscape Directory SDK para Java vía JNDI en una aplicación web con Apache Tomcat Irenio Luis Chagua Aduviri http://www.nspsac.com/ichagua/ [email protected] Versión 1.0, 04 Mayo 2007 NETSOLUTIONS PERU S.A.C. Copyright Copyright (c) 2007, Irenio Luis Chagua Aduviri. Este documento puede ser distribuido solo bajo los términos y condiciones de la licencia de Documentación de javaHispano v1.0 o posterior (la última versión se encuentra en http://www.javahispano.org/licencias/ ). Para cualquier comentario, duda, consulta sobre este tutorial dirigirse a [email protected] .

Upload: cristianlopez

Post on 12-Jun-2015

292 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK para Java vía JNDI en una aplicación web con

Apache Tomcat

Irenio Luis Chagua Aduviri http://www.nspsac.com/ichagua/

[email protected] Versión 1.0, 04 Mayo 2007

NETSOLUTIONS PERU S.A.C.

Copyright

Copyright (c) 2007, Irenio Luis Chagua Aduviri. Este documento puede ser distribuido solo bajo los términos y

condiciones de la licencia de Documentación de javaHispano v1.0 o posterior (la última versión se encuentra en

http://www.javahispano.org/licencias/).

Para cualquier comentario, duda, consulta sobre este tutorial dirigirse a [email protected].

Page 2: Articulo_LDAP
Page 3: Articulo_LDAP

Contenido del Artículo

Introducción ............................................................................................ 1

1. LDAP (Lightweight Directory Access Protocol) ............................. 3

Utilidades de LDAP ...............................................................................3 Características de LDAP.......................................................................4 Estructura del Arbol LDAP ...................................................................4

Entradas..............................................................................................4 Atributos.............................................................................................4 Tipos de Atributos .............................................................................5 Clase de Objetos ................................................................................6 LDIF ....................................................................................................6 Modelo de Nombres LDAP ................................................................6

2. Directorio LDAP............................................................................... 8

3. Browser LDAP ............................................................................... 14

4. Librería para acceder a LDAP ....................................................... 14

API JNDI...............................................................................................15 Configuración de Recursos JNDI ........................................................16

5. Creando las clases JavaBean......................................................... 18

6. Implementando las clases DAO ..................................................... 21

La interfaz DAO ...................................................................................21 La clase DAO Factory .........................................................................22 Y la implementación de la interfaz DAO.............................................22

7. Directorio SDK para Java............................................................... 24

Búsqueda de una Entrada de Directorio.............................................24 Autenticando Usuarios ........................................................................28 Creando y Manipulando entradas de directorio .................................29 Servlets, JSP y LDAP ..........................................................................33

8. Directorios LDAP ........................................................................... 37

9. Clientes LDAP................................................................................ 37

10. Librerías para LDAP................................................................... 37

11. Referencias y Herramientas utilizadas....................................... 37

Page 4: Articulo_LDAP
Page 5: Articulo_LDAP

Introducción Cuando se está desarrollando aplicaciones empresariales, muchas veces se tiene un

directorio de personas, objetos, que son necesarios tenerlos ordenado en un formato

estándar, uno de ellos es LDAP (Lightweight Directory Access Protocol), pero las

formas de acceso a este directorio son diversas, por eso se ha pensado en

implementar el acceso desde un directorio SDK para Java utilizando un servidor web

Apache Tomcat. El directorio LDAP utilizado es OpenLDAP, uno de los directorios

que está al alcance del mundo del software libre.

En este artículo se presenta el uso del directorio LDAP con la finalidad de conocer

con mayor profundidad, creando nuevas especificaciones de esquemas del directorio

y nuevas clases de objetos con sus respectivos atributos. El mismo directorio es

posible mostrar mediante un Browser LDAP en modo gráfico.

La aplicación desarrollada empieza con la creación de las entradas del directorio

LDAP, configuración de la librería Netscape Directory SDK para Java, configuración

de recursos JNDI con las clases JavaBean, implementación de las clases DAO para la

aplicación haciendo uso del mismo directorio SDK para la búsqueda, autenticación de

usuarios, creación y manipulación de las entradas de directorio y finalmente es

mostrado el acceso a LDAP mediante Servlets para enviar datos a una página web

haciendo uso de JSP.

Algunos de los pasos de la configuración de las herramientas se han obviado, en

caso de no concerlos pueden encontrar información básica en los distintos sitios

mencionados en la referencia.

1

Page 6: Articulo_LDAP
Page 7: Articulo_LDAP

1. LDAP (Lightweight Directory Access Protocol)

LDAP (Lightweight Directory Access Protocol) o Protocolo de Acceso Ligero a

Directorio es un protocolo de comunicación que permite acceder y modificar

información almacenada en un directorio ordenado y distribuido en forma jerárquica,

actualmente está en la versión 3. LDAP permite almacenar información de cuentas de

usuario, contactos, ubicación de diversos recursos de la red, permisos de usuarios,

certificados, entre otros; éste directorio está optimizado para acceso de lectura en

forma eficiente y almacenar datos de poco tamaño, las modificaciones se presentan con

poca frecuencia como el caso de un correo electrónico.

El protocolo LDAP accede a la información contenida en un árbol de información de

directorio, las cuales están formados por un conjunto de atributos, indicando el nombre

y su respectivo valor. Este directorio es único en una organización y es posible acceder

de diversas aplicaciones.

Utilidades de LDAP Directorios de información, por ejemplo datos de empleados organizados por

departamentos (siguiendo la estructura organizativa de la empresa) ó cualquier tipo

de páginas amarillas.

Sistemas de autenticación/autorización centralizada, sistemas donde se guarda gran

cantidad de registros y se requiere un uso constante de los mismos, por ejemplo,

gestión de cuentas de acceso a una red corporativa, sistema de autenticación para

páginas web, sistemas de control de entradas a edificios, oficinas, entre otros.

Sistemas de correo electrónico.

Sistemas de alojamiento de páginas web y FTP.

Sistemas de autenticación basados en RADIUS, para el control de accesos de los

usuarios a una red de conexión o ISP.

Servidores de certificados públicos y llaves de seguridad.

Autenticación única ó “single sign-on” para la personalización de aplicaciones.

Perfiles de usuarios centralizados, para permitir itinerancia ó “Roaming”.

Libretas de direcciones compartidas.

3

Page 8: Articulo_LDAP

LDAP (Lightweight Directory Access Protocol)

Características de LDAP Operaciones de lectura muy rápidas. Debido a la naturaleza de los datos

almacenados en los directorios las lecturas son más comunes que las escrituras.

Datos relativamente estáticos. Los datos almacenados en los directorios no suelen

actualizarse con mucha frecuencia.

Entorno distribuido, fácil replicación.

Estructura jerárquica. Los directorios almacenan la información de forma jerárquica

de forma nativa.

Orientadas a objetos. El directorio representa a elementos y a objetos. Los objetos

son creados como entradas, que representan a un conjunto de atributos.

Esquema estándar. Los directorios utilizan un sistema estándar que pueden usar

fácilmente diversas aplicaciones.

Atributos multi-valor. Los atributos pueden almacenar un valor único o varios.

Replicación multi-master. Muchos de los servidores LDAP permiten que se realicen

escrituras o actualizaciones en múltiples servidores.

Estructura del Árbol LDAP

Entradas

El modelo de información de LDAP está basado en entradas. Una entrada es un conjunto

de atributos que tienen un único Nombre Distintivo DN (Distinguished Name) y de forma

global. El DN se utiliza para referirse a una entrada sin ambigüedades. Cada atributo de

una entrada tiene un tipo y está asociado uno o más valores. Los tipos son normalmente

palabras nemotécnicas, como "cn" para common name, o "mail" para una dirección de

correo electrónico.

La sintaxis de los atributos depende del tipo de atributo. Por ejemplo, un atributo cn

puede tener el valor “Mariano Apaza Quispe”. Un atributo mail puede contener un valor

[email protected]”. El atributo jpegPhoto contiene una fotografía en formato JPEG.

Atributos

Los datos del directorio son un conjunto de atributos y sus respectivos valores. Por

ejemplo el atributo commonName, o cn, se usa para representar el nombre de una persona.

Los datos de una persona que se registra en el directorio se definen mediante el

conjunto de atributos que están definidas en las especificaciones de esquemas, en este

caso la clase de objetos person.

En una entrada de directorio se presentan atributos obligatorios que deben estar

presentes en la clase de objetos y atributos opcionales que no es necesario que esté

presente en una entrada de clase de objetos.

Irenio Luis Chagua Aduviri

Page 9: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

Tipos de Atributos

Una definición de tipo de atributo especifica la sintaxis de un atributo y cómo se

ordenan y comparan los atributos de ese tipo.

Los tipos de atributos en el directorio forman un árbol de clases. Por ejemplo, el tipo de

atributo "commonName" es una subclase del tipo de atributo "name". Hay atributos

obligatorios y opcionales que se muestran en la Tabla 1.1.

TABLA 1.1: RFC 2252: AttributeTypeDescription

Identificador de

Atributo

Descripción del Valor de Atributo

NUMERICOID

(obligatorio)

Identificador de Objeto Único (OID)

NAME Nombre del Atributo

DESC Descripción del Atributo

OBSOLETE "true" si es obsoleto; "false" o ausente si no lo es

SUP Nombre del tipo de atributo superior del que se deriva el tipo de

atributo

EQUALITY Nombre ó OID de la regla de correspondencia si la igualdad de

correspondencia está permitida; ausente si no lo está

ORDERING Nombre ó OID de la regla de correspondencia si está permitida la

ordenación; ausente si no lo está.

SUBSTRING Nombre ó OID de la regla de correspondencia si está permitida la

correspondencia de sub-string ausente si no lo está.

SYNTAX OID numérico de la sintaxis de los valores de este tipo

SINGLE-VALUE "true" si el atributo no es multi-valor; "false" o ausente si lo es

COLLECTIVE "true" si el atributo es colectivo; "false" o ausente si no lo es

NO-USER-

MODIFICATION

"true" si el atributo no es modificable por el usuario; "false" o

ausente si lo es

USAGE Descripción del uso del atributo

Irenio Luis Chagua Aduviri

Page 10: Articulo_LDAP

LDAP (Lightweight Directory Access Protocol)

Clase de Objetos

En LDAP, una clase de objetos define el conjunto de atributos a ser usados para definir

una entrada. El estándar LDAP proporciona estos tipos básicos para las clases de

objetos:

1. Grupos en el directorio, entre ellos listas no ordenadas de objetos individuales o de

grupos de objetos.

2. Emplazamientos, como por ejemplo el nombre del país y su descripción.

3. Organizaciones que están en el directorio.

4. Personas que están en el directorio.

Una entrada determinada puede pertenecer a más de una clase de objetos. Por ejemplo,

la entrada para personas se define mediante la clase de objetos person, pero también

puede definirse mediante atributos en las clases de objetos inetOrgPerson, groupOfNames

y organization. La estructura de clases de objetos del servidor determina la lista total

de atributos requeridos y permitidos para una entrada concreta.

LDIF

El formato de intercambio de LDAP es un archivo de texto que almacena información de

entradas de objetos en forma jerárquica. Esto nos permite importar y exportar

información de directorio entre servidores de directorios basados en LDAP.

Modelo de Nombres LDAP

Cada entrada de directorio LDAP está organizada en un árbol de información de

directorio y para identificar a alguna entrada de directorio se accede mediante su

nombre distintivo (DN). Cada nombre distintivo puede estar formado por una secuencia

de nombres distintivos relativos RDN (Relative Distinguished Name), como uid=mapaza.

Cada nombre distintivo relativo en un DN corresponde a una rama del árbol de

información de directorio. Asimismo está formado por otros atributos que lo relacionan

con las jerarquías superiores como componentes de dominio DC (Domain Component),

así, dc=nspsac, dc=com. Después del nombre distintivo hay una serie de atributos que

definen las entradas.

Para comprender un poco sobre la estructura del directorio veamos el árbol de la

gráfica donde se describe a la empresa nspsac.com como principal y teniendo como

unidades organizacionales a Admin, People y Developer, de las cuales en cada unidad

organizacional es posible agregar directorios, en este caso una cuenta de usuario con

su información de datos de identificación, registro del empleado, datos de su jefe,

correo electrónico, teléfono fijo, teléfono celular, la dirección en la que vive, la clave de

identificación de la cuenta y la foto correspondiente del empleado.

Irenio Luis Chagua Aduviri

Page 11: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

FIGURA 1.1 Árbol de Directorio LDAP

La información descrita anteriormente para que se encuentre registrado en el directorio

LDAP creamos un formato LDIF estándar, que es un archivo de texto que contiene

información de configuración LDAP y contenido de directorios, en este caso será

mapaza.ldif que se muestra a continuación:

dn: uid=mapaza,ou=People,dc=nspsac,dc=com givenName: Mariano sn: Apaza Quispe mail: [email protected] objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: contribuyente uid: mapaza cn: Mariano Apaza Quispe dni: 01234567 ruc: 10012345675 employeeNumber: A214 manager: uid=jperez,ou=Admin,dc=nspsac,dc=com telephoneNumber: 051505050 mobile: 0519797979 direccion: Jr. Los Incas Nro. 6548 st: Puno l: Ilave userPassword: abc jpegPhoto:<file:///var/photo.jpg

Además al crear un directorio de entrada los atributos pertenecen a un conjunto de

clase de objetos que están definidos en una especificación de esquemas según el

estándar, en este caso pertenece a la clase de objetos person, organizationalPerson,

inetOrgPerson y contribuyente, de éste último veremos más adelante.

Irenio Luis Chagua Aduviri

Page 12: Articulo_LDAP

Directorio LDAP

2. Directorio LDAP Para almacenar estas descripciones de directorios es necesario el uso de un directorio

LDAP, hay varias implementaciones de estos directorios, de distintas empresas, para

distintos usos y para aplicaciones diferentes. Para el caso del presente artículo haremos

uso de OpenLDAP, un directorio LDAP a nuestro alcance en el mundo del software

libre.

Para descargar el instalador de OpenLDAP acceda a http://www.openldap.org/, ó si

desea OpenLDAP para Windows. Una vez descargado e instalado OpenLDAP es

necesario modificar el archivo de configuración slapd.conf, este archivo contiene

configuración de usuario, contraseña, sufijo, dn principal, especificaciones de esquemas,

entre otros. En este caso cambiaremos algunos valores de los atributos.

database bdb suffix "dc=nspsac,dc=com" rootdn "cn=root,dc=nspsac,dc=com" rootpw abc directory ./data

Se ha realizado el cambio del sufijo a "dc=nspsac,dc=com", y dn principal a

"cn=root,dc=nspsac,dc=com", luego la contraseña de la cuenta principal se ha cambiado

a abc, pero también es posible colocar una contraseña encriptada con {CRYPT}, {MD5},

{SMD5}, {SSHA}, y {SHA}, si usamos alguna de estas encriptaciones la contraseña de la

cuenta principal quedaría como el siguiente:

rootpw {SSHA}/Wg8V59/aoeKLn4PkkKWEsdvjyz6R+/E

Muchos de los atributos de la entrada de directorio descrito anteriormente no está

disponible en la configuración inicial, estos atributos están basados en unas

especificaciones de esquemas que delimitan su creación. Para esto quitaremos el

comentario ó agregaremos si no está descrito de las siguientes especificaciones de

esquemas:

include ./schema/core.schema include ./schema/cosine.schema include ./schema/inetorgperson.schema

Los atributos dni, ruc, y direccion no está definido en las especificaciones de

esquemas que acabamos de activarlas, estos atributos lo he agregado para fines de

conocer cómo se crea una nueva especificación de esquemas y por otro lado en mi país

(Perú) todo usuario de un sistema al menos tiene su documento nacional de identidad

(DNI), su registro único del contribuyente (RUC) y se agregó el atributo dirección por

comodidad, aunque el atributo dni y direccion no debiera estar definido en una clase

de objetos como la de contribuyente, más bien debería estar definido en la clase de

objetos person, para efectos de no complicar la configuración se ha añadido en la clase

de objeto contribuyente.

Irenio Luis Chagua Aduviri

Page 13: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

En una especificación de esquema se definen clases de objetos válidos que indican qué

atributos debe contener en forma obligatoria y qué atributos son opcionales, así como el

tipo de dato (cadenas de texto, números) de un atributo. La clase de objetos y los

atributos deben estar definidos en forma global y único mediante cadenas de números

(OID), para esto es necesario obtener un OID que nos permitirá crear tantas

extensiones como se quiera del esquema.

Los tipos de clase de objetos que existen son tres: Structural. Una clase de objeto

estructural define las características básicas de un objeto. Auxiliary. Una clase de

objeto Auxiliar es adicional, complementa los atributos de una clase de objeto

estructural. Y por último Abstract. Esta clase de objeto abstracto es usado solamente

para definir modelo de datos LDAP básicos.

La sintaxis básica para crear una clase de objetos es la siguiente:

objectclass ( 1.1.2.2.2 NAME 'myPerson' DESC 'Mi persona' SUP inetOrgPerson MUST ( myUniqueName $ givenName ) MAY myPhoto )

Donde:

1.1.2.2.2 es el identificador único global (OID).

NAME 'myPerson' es el nombre de la clase de objeto (alias para OID).

DESC 'Mi persona' la descripción para la clase de objeto.

SUP inetOrgPerson es el objeto del que hereda.

MUST(...) aquí se describen los atributos requeridos.

MAY(...) aquí se describen los atributos opcionales.

La sintaxis básica para crear un atributo es la siguiente:

attributetype ( 1.3.6.1.1.1.1.0 NAME 'uidNumber' DESC 'Identifica en forma única a un usuario' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )

Donde:

1.3.6.1.1.1.1.0 es el identificador único global (OID).

NAME 'uidNumber' es el nombre del atributo (alias para OID).

DESC '...' la descripción para el atributo.

EQUALITY integerMatch calificador de plantilla de tipos.

SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 es la sintaxis OID.

SINGLE-VALUE es un calificador, puede ser SINGLE-VALUE, COLLECTIVE y {LENGTH}.

Irenio Luis Chagua Aduviri

Page 14: Articulo_LDAP

Directorio LDAP

La Sintaxis de los atributos se presenta en la Tabla 2.1.

TABLA 2.1: Sintaxis de los atributos

Tipo de Dato OID Descripción

Binary 1.3.6.1.4.1.1466.115.121.1.5 BER/DER data

Boolean 1.3.6.1.4.1.1466.115.121.1.7 boolean value

Distinguished Name 1.3.6.1.4.1.1466.115.121.1.12 DN

Directory String 1.3.6.1.4.1.1466.115.121.1.15 UTF-8 string

IA5String 1.3.6.1.4.1.1466.115.121.1.26 ASCII string

Integer 1.3.6.1.4.1.1466.115.121.1.27 Integer

Name and Optional UID 1.3.6.1.4.1.1466.115.121.1.34 DN plus UID

Numeric String 1.3.6.1.4.1.1466.115.121.1.36 Numeric String

OID 1.3.6.1.4.1.1466.115.121.1.38 Object Identifier

Octet String 1.3.6.1.4.1.1466.115.121.1.40 Arbitrary Octets

Printable String 1.3.6.1.4.1.1466.115.121.1.44 Printable String

Las Reglas de las plantillas de atributos se presenta en la Tabla 2.2.

TABLA 2.2: Reglas de plantillas de atributos

Nombre Contexto Descripción

booleanMatch equality Boolean

objectIdentiferMatch equality OID

distinguishedNameMatch equality DN

uniqueMemberMatch equality DN with optional UID

numericStringMatch equality numerical

numericStringOrdering ordering numerical

numericStringSubstringsMatch substrings numerical

caseIgnoreMatch equality case insensitive, space insensitive

caseIgnoreOrderingMatch ordering case insensitive, space insensitive

caseIgnoreSubstringsMatch substrings case insensitive, space insensitive

caseExactMatch equality case sensitive, space insensitive

caseExactOrderingMatch ordering case sensitive, space insensitive

caseExactSubstringsMatch substrings case sensitive, space insensitive

caseIgnoreIA5Match equality case insensitive, space insensitive

caseIgnoreIA5OrderingMatch ordering case insensitive, space insensitive

caseIgnoreIA5SubstringsMatch substrings case insensitive, space insensitive

caseExactIA5Match equality case sensitive, space insensitive

caseExactIA5OrderingMatch ordering case sensitive, space insensitive

caseExactIA5SubstringsMatch substrings case sensitive, space insensitive

Irenio Luis Chagua Aduviri

Page 15: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

Regresando nuevamente a la clase de objeto contribuyente y con la base de los

conceptos para crear las clases de objetos y atributos en una especificación de

esquema, se define el esquema en el archivo de texto con el nombre

contribuyente.schema en el directorio schema de la ruta donde está instalado

OpenLDAP, con el siguiente contenido:

# # OID prefix: 1.3.6.1.4.1.10018 # # Attributes: 1.3.6.1.4.1.10018.1.1 # attributetype ( 1.3.6.1.4.1.10018.1.1.1 NAME 'ruc' DESC 'Registro Único del Contribuyente' EQUALITY numericStringMatch SUBSTR numericStringSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{11} ) attributetype ( 1.3.6.1.4.1.10018.1.1.2 NAME 'razonSocial' DESC 'Razón Social del Contribuyente' SUP name ) attributetype ( 1.3.6.1.4.1.10018.1.1.3 NAME 'dni' DESC 'Documento Nacional de Identidad de la Persona' EQUALITY numericStringMatch SUBSTR numericStringSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{8} ) attributetype ( 1.3.6.1.4.1.10018.1.1.4 NAME 'dniRepLegal' DESC 'Documento Nacional de Identidad del Representante Legal del contribuyente' EQUALITY numericStringMatch SUBSTR numericStringSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{8} ) attributetype ( 1.3.6.1.4.1.10018.1.1.5 NAME 'estadoDomicilio' DESC 'Estado del Domicilio del contribuyente' SUP name ) attributetype ( 1.3.6.1.4.1.10018.1.1.6 NAME 'direccion' DESC 'Domicilio de la Persona' SUP name ) # # Objects: 1.3.6.1.4.1.10018.1.2 # objectclass ( 1.3.6.1.4.1.10018.1.2.1 NAME 'contribuyente' DESC 'contribuyente' SUP top AUXILIARY MUST ( ruc $ dni ) MAY ( dniRepLegal $ estadoDomicilio $ razonSocial $ direccion) )

La especificación de esquema contribuyente debe ser agregado en el archivo de

configuración slapd.conf la siguiente línea.

include ./schema/contribuyente.schema

Irenio Luis Chagua Aduviri

Page 16: Articulo_LDAP

Directorio LDAP

Una vez creado el archivo y guardado reiniciamos nuestro servicio de directorio

OpenLDAP.

Antes de continuar con agregar el directorio definido anteriormente en el fichero

mapaza.ldif es necesario crear las unidades organizacionales, tal como se ha visto en

el árbol LDAP del gráfico, sino creamos estas unidades organizacionales no es posible

agregar esta entrada de directorio. Para esto creamos un archivo de texto con el

nombre ounspsac.ldif con el siguiente contenido.

dn: ou=Admin,dc=nspsac,dc=com objectClass: top objectClass: organizationalUnit ou: Admin dn: ou=People,dc=nspsac,dc=com objectClass: top objectClass: organizationalUnit ou: People dn: ou=Developer,dc=nspsac,dc=com objectClass: top objectClass: organizationalUnit ou: Developer

Para agregar un directorio de entrada LDAP en formato LDIF ejecutaremos el siguiente

comando.

slapadd -v -f slapd.conf -l ounspsac.ldif

De otra forma también es posible insertar los datos de entrada del directorio con el

siguiente comando.

ldapadd -x -D "cn=root,dc=nspsac,dc=com" -w abc -f ounspsac.ldif

De modo similar ahora añadimos al directorio LDAP lo que habíamos definido

inicialmente.

slapadd -v -f slapd.conf -l mapaza.ldif

Y así añadimos otras entradas de directorio LDAP, pero ahora la contraseña del usuario

será encriptado con {SSHA} y es de la siguiente manera.

Irenio Luis Chagua Aduviri

Page 17: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

dn: uid=jmamani,ou=People,dc=nspsac,dc=com givenName: Juan Antonio sn: Mamani Choque mail: [email protected] objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: contribuyente uid: jmamani cn: Juan Antonio Mamani Choque dni: 01847569 ruc: 10018475691 employeeNumber: 2097 mobile: 0519535353 direccion: Av. Titicaca Nro. 458 st: Puno l: Juli userPassword: {SSHA}IabIHNeVpLkbzDxCANEMj47OJ9QRh9Gj

Para generar una cadena de texto encriptada se hace uso del comando slappasswd que

trae OpenLDAP de la siguiente manera:

slappasswd -h {SSHA} -s abc

Y continuando con agregar una entrada de directorio LDAP.

slapadd -v -f slapd.conf -l jmamani.ldif

Como se ha visto se ha tenido que agregar en tres veces las entradas de directorio

LDAP definidos, pero no es necesario realizar para cada entrada de directorio, es

posible juntar las tres entradas de directorio en un solo formato LDIF denominado

nspsac.ldif.

Luego de haber insertado datos de entrada de directorio podemos hacer uso del

comando slapcat para mostrar todas las entradas de directorio que se encuentra en

nuestro directorio LDAP en formato LDIF, esto mismo nos puede servir para guardar

estas entradas para lo que sea necesario.

Si se desea realizar una búsqueda mediante un DN es mediante el comando ldapsearch.

ldapsearch -x -b "uid=jmamani,ou=People,dc=nspsac,dc=com"

Asimismo es posible eliminar entradas de directorio LDAP mediante el comando

ldapdelete.

ldapdelete -x -D "cn=root,dc=nspsac,dc=com" -w abc "uid=jmamani,ou=People,dc=nspsac,dc=com"

Irenio Luis Chagua Aduviri

Page 18: Articulo_LDAP

Browser LDAP

3. Browser LDAP Hasta aquí hemos visto las operaciones de entradas de directorio OpenLDAP desde

líneas de comando, se puede utilizar en modo gráfico mediante un navegador de LDAP,

para esto utilizaremos LDAPBrowser que está basado en Java y ejecutamos la shell

lbe.bat y configuramos como la que se muestra en la figura. Con esto es posible

administrar un directorio LDAP en modo gráfico.

FIGURA 3.1 Configuración LDAP Browser

4. Librería para acceder a LDAP Lo anterior ha sido una descripción breve sobre el manejo de un directorio LDAP, pero

cuando se quiere incluir el uso de directorios LDAP en aplicaciones empresariales es

necesario utilizar una librería para acceder a la información de los directorios, como un

lenguaje de programación. Para el presente artículo haremos uso de una librería

desarrollada por Netscape, un directorio SDK para Java que también está a nuestro

alcance en el mundo de software libre. Una vez descargado el código fuente y

compilado según las instrucciones de cómo generar la librería de Netscape, que también

pueden bajárselo una de las librerías que he compilado ldapjdk.jar será posible integrar

en las aplicaciones empresariales el acceso a un directorio LDAP.

Para realizar búsquedas y localizar información en diversos sistemas como directorios

LDAP es necesario una interfaz de múltiples servicios de directorio y de nombres como

JNDI (Java Naming Directory Interface). JNDI nos permitirá interactuar desde Java con

OpenLDAP, esto mediante un proveedor de servicios de interfaz SPI (Service Provider

Interface), que en este caso es el mismo Netscape que ha desarrollado junto a la

librería para el acceso a LDAP, con el nombre Service Provider LDAP que también

pueden bajárselo ldapsp.jar.

Los archivos generados, una vez compilado el código fuente, específicamente del

directorio packages, es necesario que los archivos JAR sean agregados a la variable de

Irenio Luis Chagua Aduviri

Page 19: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

entorno CLASSPATH del sistema operativo, asumiendo que en windows se ha creado en

el directorio c:\netscape\ldapjava y en FreeBSD ó UNIX en el direcotorio

/usr/netscape/ldapjava, que lo llamaremos a esta ruta de directorio como

<LDAPSDKHOME>. Mediante los siguientes comandos agregamos a la variable de entorno.

En Linux CLASSPATH=<LDAPSDKHOME>/packages/ldapjdk.jar:<LDAPSDKHOME>/ packages/ldapsp.jar:$CLASSPATH export CLASSPATH

En FreeBSD, Unix setenv CLASSPATH <LDAPSDKHOME>/packages/ldapjdk.jar:<LDAPSDKHOME>/ packages/ldapsp.jar:$CLASSPATH

En Windows set CLASSPATH=<LDAPSDKHOME>/packages/ldapjdk.jar;<LDAPSDKHOME>/ packages/ldapsp.jar;%CLASSPATH%

API JNDI Mediante el API de JNDI es posible escribir cualquier tipo de programa para acceder a

información en directorios LDAP, gestores de Base de datos relacionales, servicios

CORBA (COS, Corba Object Service), NDS de Novell, entre otras aplicaciones. Para que

un programa de Java busque información de cualquier tipo en un directorio LDAP debe

indicarse dentro del programa la ubicación del directorio LDAP mediante un Naming

Manager para la ubicación física del sistema. Esto es importante ya que en cualquier

momento es posible cambiar el servidor físico del directorio LDAP y no será necesario

la modificación de programa fuente para luego compilarlo, sino basta con cambiar los

parámetros de configuración.

FIGURA 4.1 API JNDI

Irenio Luis Chagua Aduviri

Page 20: Articulo_LDAP

Librería para acceder a LDAP

Configuración de Recursos JNDI Para realizar una consulta a una entrada de directorio LDAP mediante la librería

Netscape Directory SDK para Java, será necesario la configuración de JNDI en un

servidor web, para este artículo lo voy a desarrollar en una aplicación web con Apache Tomcat. El cual trae una implementación JNDI InitialContext para cada instancia de

aplicación web que se encuentre ejecutando bajo este servidor. Para esto será

necesario que descarguen el instalador de Apache Tomcat y configuralo. El servidor

Tomcat es una aplicación web basada en Java creada para ejecutar servlets y páginas

JSP que nos ayudará para este propósito.

Para este caso se creará una aplicación web con una estructura de directorios básico, lo

nombraremos ldap que se encontrará en el directorio $CATALINA_HOME/webapps. Luego

es necesario incluir un descriptor de la aplicación que es el archivo web.xml que

contendrá la configuración de la aplicación web y estará dentro del directorio WEB-INF/

del directorio raíz de la aplicación creada, es decir $CATALINA_HOME/webapps/ldap/WEB-

INF/web.xml.

Las entradas InitialContext en una aplicación web son configurados en un elemento

<Context> que puede estar definido en $CATALINA_HOME/conf/server.xml ó de

preferencia el archivo XML del contexto de la aplicación dentro de META-

INF/context.xml

Los recursos definidos en estos elementos pueden estar referidos por los siguientes

elementos al utilizar la descripción de una aplicación web que se encuentra en /WEB-

INF/web.xml:

<env-entry> - Es la entrada del entorno de la aplicación, un parámetro de valor

simple, puede ser usado para configurar de cómo la aplicación funcionará.

<resource-ref> - Es la referencia del recurso de la aplicación, que es un objeto

Factory para recursos como JDBC DataSource, JavaMail Session ó un objeto Factory

personalizado.

<resource-env-ref> - Es el Recurso de referencia del entorno de aplicación, es una

nueva variación del elemento <resource-ref> añadido en Servlet 2.4 que es más

simple de configurar para recursos que no necesitan información de autenticación.

Irenio Luis Chagua Aduviri

Page 21: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

Para el caso de nuestra aplicación definiremos el elemento <resource-env-ref> en el

descriptor de la aplicación web.xml con el siguiente contenido.

<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <resource-env-ref> <description> Objeto Factory para una instancia de BeanLDAPHost. </description> <resource-env-ref-name> beanldaphost </resource-env-ref-name> <resource-env-ref-type> com.nspsac.bean.BeanLDAPHost </resource-env-ref-type> </resource-env-ref> </web-app>

Como habrán notado en este descriptor de la aplicación hacemos referencia a un

recurso de la aplicación con el nombre beanldaphost que es de tipo de clase JavaBean

com.nspsac.bean.BeanLDAPHost, que luego se implementará.

Cada recurso JNDI disponible es configurado en base a una inclusión de los siguientes

elementos dentro de un elemento <Context> ó un elemento <DefaultContext>:

<Environment> - Configura nombres y valores de entradas de entorno de aplicación

que estará en funcionamiento a través de JNDI InitialContext.

<Resource> - Configura el nombre y el tipo de dato de un recurso disponible para la

aplicación.

<ResourceLink> - Agrega un enlace a un recurso definido en el contexto JNDI

global.

Para configurar el recurso JNDI en nuestra aplicación agregamos el <Context> en el

archivo de configuración $CATALINA_HOME/conf/server.xml que es el recurso que hacemos referencia con el nombre beanldaphost.

<Context path="ldap" docBase="ldap" reloadable="true" override="true"> <Resource name="beanldaphost" auth="Container" type="com.nspsac.bean.BeanLDAPHost" factory="com.nspsac.bean.BeanLDAPHostFactory" iphost="localhost" puerto="389" dnbase="dc=nspsac,dc=com" dnmgr="cn=root" dnpwd="abc" dnraiz="ou=People" ctxfactory="com.netscape.jndi.ldap.LdapContextFactory"/> </Context>

Irenio Luis Chagua Aduviri

Page 22: Articulo_LDAP

Creando las clases JavaBean

En este recurso JNDI estará almacenado la información necesaria para acceder a un

directorio LDAP desde una aplicación web; como habrán notado, este recurso utiliza una

clase JavaBean y el Resource Factory que es una clase también JavaBean asociado

mediante el atributo factory con el valor com.nspsac.bean.BeanLDAPHostFactory, y los

demás atributos (iphost, puerto, dnbase, dnmgr, dnpwd y dnraiz) de este elemento

<Resource> son información que utilizaremos dentro de las clases JavaBean para

realizar la conexión hacia el directorio LDAP definido anteriormente. Adicionalmente,

podemos apreciar el atributo ctxfactory asociado a un proveedor de servicios de

interfaz (SPI) tal como habíamos indicado anteriormente.

En esta configuración el atributo factory hace referencia a un Resource Factory, pero

según la configuración de tomcat podemos incluir de la siguiente forma

"org.apache.naming.factory.BeanFactory", y por razones de personalizar nuestra

aplicación, se ha creado una clase JavaBean propio.

5. Creando las clases JavaBean Según la configuración JNDI que se ha definido en el descriptor de la aplicación y en el

Resource Factory, ahora implementamos nuestra clase JavaBean con el nombre

BeanLDAPHost, esto será llamado cada vez que la aplicación se ejecute asociado a

Resource Factory.

package com.nspsac.bean; import java.io.Serializable; import java.util.Hashtable; public class BeanLDAPHost implements Serializable { private Hashtable htLdap; public BeanLDAPHost(String iphost, int puerto, String dnmgr, String dnpwd, String dnbase, String dnraiz, String ctxfactory) { this(iphost, Integer.toString(puerto), dnmgr, dnpwd, dnbase, dnraiz, ctxfactory); } public BeanLDAPHost(String iphost, String puerto, String dnmgr, String dnpwd, String dnbase, String dnraiz, String ctxfactory) { htLdap = new Hashtable(); htLdap.put("ldap_iphost", iphost); htLdap.put("ldap_puerto", puerto); htLdap.put("ldap_dnmgr", dnmgr); htLdap.put("ldap_dnpwd", dnpwd); htLdap.put("ldap_dnbase", dnbase); htLdap.put("ldap_dnraiz", dnraiz); htLdap.put("ldap_ctxfactory", ctxfactory); }

Irenio Luis Chagua Aduviri

Page 23: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

public String getAttribute(String name) throws Exception { if null || name.equals("")) (name == throw new Exception(); else return (String)htLdap.get(name); } }

El Resource Factory predeterminado de Apache a veces puede resultarnos limitado para

ciertas operaciones, por tal razón creamos nuestro Resource Factory propio para luego

integrarlo en Tomcat, la clase JavaBean Resource Factory personalizado le hemos dado

el nombre de BeanLDAPHostFactory.

Para escribir la clase Resource Factory se debe implementar la interfaz del proveedor

de servicio JNDI javax.naming.spi.ObjectFactory. Cada vez que la aplicación web

llama al método lookup() en una entrada del contexto que está asociado a este

Factory, el método getObjectInstance() es invocado con los siguientes argumentos:

Object obj – El objeto que contiene la localización ó referencia de la información

que puede ser usado en la creación del objeto.

Name name – Es el nombre al que este Factory está relacionado a nameCtx, ó null si

el nombre no está especificado.

Context nameCtx – El contexto relacionado al que el nombre del parámetro es

especificado, ó null si el nombre está relacionado al contexto inicial por defecto.

Hashtable environment – Es el entorno que es utilizado en la creación de este

objeto.

package com.nspsac.bean; import java.util.Enumeration; import java.util.Hashtable; import javax.naming.Context; import javax.naming.Name; import javax.naming.NamingException; import javax.naming.RefAddr; import javax.naming.Reference; import javax.naming.spi.ObjectFactory; public class BeanLDAPHostFactory implements ObjectFactory { public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws NamingException { BeanLDAPHost bean = null; Reference ref = (Reference) obj; Enumeration addrs = ref.getAll(); String iphost = null; int puerto = -1; String dnbase = null; String dnmgr = null; String dnpwd = null; String dnraiz = null; String ctxfactory = null;

Irenio Luis Chagua Aduviri

Page 24: Articulo_LDAP

Creando las clases JavaBean

while (addrs.hasMoreElements()) { RefAddr addr = (RefAddr) addrs.nextElement(); String nombre = addr.getType(); String value = (String) addr.getContent(); if (nombre.equals("iphost")) { iphost = value; } else if (nombre.equals("puerto")) { try { puerto = Integer.parseInt(value); } catch (NumberFormatException e) { throw new NamingException("Invalid 'port' value " + value); } } else if(nombre.equals("dnbase")){ dnbase = value; } else if(nombre.equals("dnmgr")){ dnmgr = value; } else if(nombre.equals("dnpwd")){ dnpwd = value; } else if(nombre.equals("dnraiz")){ dnraiz = value; } else if(nombre.equals("ctxfactory")){ ctxfactory = value; } } bean = new BeanLDAPHost(iphost,puerto,dnmgr,dnpwd, dnbase,dnraiz,ctxfactory); return (bean); } }

Para compilar las clases JavaBean que hemos creado es necesario que la librería que

estamos utilizando del proveedor de servicios de interfaz de Netscape Directory SDK

para Java ldapsp.jar esté incluido dentro del directorio de librerías de Tomcat que es

$CATALINA_HOME/common/lib. Adicionalmente la librería SDK ldapjdk.jar también deberá

estar incluido en este directorio de librerías de Tomcat para que funcione nuestros

ejemplos de este artículo.

Irenio Luis Chagua Aduviri

Page 25: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

6. Implementando las clases DAO Para implementar los accesos a un directorio LDAP mediante una aplicación web

utilizaremos el modelo DAO, que es utilizado para separar las operaciones de los datos

de bajo nivel desde un nivel más alto de la lógica de negocio. Una aplicación DAO tiene

los siguientes componentes:

Una clase DAO factory

Una interfaz DAO

Una clase concreta que implemente la interfaz DAO

Transferencia de objetos de datos

La interfaz DAO package com.nspsac.seguridad.ldap; import java.util.HashMap; import javax.naming.NamingException; import com.nspsac.utils.exception.IncompleteConversationalState; public interface AccesoLDAP{ static final String DIR_IMGS = "../webapps/ldap/imgs/"; static final String[] ATTRS = {"dn","mail","uid","cn", "dni","ruc","employeeNumber","jpegPhoto","manager","givenName", "telephoneNumber","mobile","direccion","sn","st","l"}; static final String OBECT_CLASS[] = { "top", "person", "organizationalPerson", "inetOrgPerson", "contribuyente"}; public void getInstance() throws NamingException; public void cambiarClave(String uid, String claveanterior, String clave) throws NamingException; public void addEntry(String uid, HashMap attrs); public void renameEntry(String uid, String newUid); public void renameEntry(String uid, String newUid, String newGroup); public void deleteEntry(String uid); public void addAttribute(String uid, String nameAttr, String valAttr) throws NamingException; public void modifyAttribute(String uid, String nameAttr, String valAttr) throws NamingException; public void deleteAttribute(String uid, String nameAttr) throws NamingException; public HashMap findByEmployeeNumber(String codPers) throws IncompleteConversationalState;

Irenio Luis Chagua Aduviri

Page 26: Articulo_LDAP

Implementando las clases DAO

public ashMap findByUID(String uid) H throws IncompleteConversationalState; public HashMap autenticar(String uid, String pwd) throws NamingException, IncompleteConversationalState; }

La clase DAO Factory package com.nspsac.seguridad.ldap; import javax.naming.NamingException; import com.nspsac.seguridad.ldap.AccesoLDAP; import com.nspsac.seguridad.ldap.AccesoLDAPImpl; public class A DAPFactory { ccesoL public static AccesoLDAP create() throws NamingException { return new AccesoLDAPImpl(); } }

Y la implementación de la interfaz DAO La clase InitialContext es configurado como una aplicación web que es desplegado

inicialmente, y está disponible para los componentes de la aplicación web (para acceso

de solo lectura). Todas las entradas y recursos configurados están asociados al espacio

de nombre JNDI java:comp/env para su acceso a un recurso. Para el caso de nuestra

clase JavaBean estaría configurado como la que se muestra en el código siguiente.

package com.nspsac.seguridad.ldap; import java.io.*; import java.util.*; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.BasicAttribute; import javax.naming.directory.InitialDirContext; import javax.naming.directory.DirContext; import javax.naming.directory.ModificationItem; import netscape.ldap.LDAPAttribute; import netscape.ldap.LDAPAttributeSet; import netscape.ldap.LDAPConnection; import netscape.ldap.LDAPEntry; import netscape.ldap.LDAPException; import netscape.ldap.LDAPSearchConstraints; import netscape.ldap.LDAPSearchResults; import netscape.ldap.LDAPv3; import com.nspsac.bean.BeanLDAPHost; import com.nspsac.utils.exception.IncompleteConversationalState; public class AccesoLDAPImpl implements AccesoLDAP{ private Hashtable htEnv;

Irenio Luis Chagua Aduviri

Page 27: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

private DirContext nspsacCtx; public nitialDirContext getInitialDirContext() throws NamingException { I return (InitialDirContext)nspsacCtx; } public void getInstance() throws NamingException { htEnv = getEnvironment(); Hashtable htJndi = new Hashtable(); htJndi.put("java.naming.factory.initial", (String)htEnv.get("DN_CTX")); htJndi.put("java.naming.provider.url", (String)htEnv.get("DN_HOST_PORT")); htJndi.put("java.naming.security.principal", (String)htEnv.get("DN_MGR")); htJndi.put("java.naming.security.credentials", (String)htEnv.get("DN_PWD")); nspsacCtx = new InitialDirContext(htJndi); } public Hashtable getEnvironment() throws NamingException { InitialContext initCtx = null; Hashtable htEnv = new Hashtable(); try { initCtx = new InitialContext(); Context ctx = (Context)initCtx.lookup("java:comp/env"); BeanLDAPHost beanldaphost = (BeanLDAPHost)ctx.lookup("beanldaphost"); String host_port = new StringBuffer("ldap://").append( beanldaphost.getAttribute("ldap_iphost")).append(":").append( beanldaphost.getAttribute("ldap_puerto")).toString(); htEnv.put("DN_HOST", beanldaphost.getAttribute("ldap_iphost")); htEnv.put("DN_PORT", beanldaphost.getAttribute("ldap_puerto")); htEnv.put("DN_HOST_PORT", host_port); htEnv.put("DN_MGR", beanldaphost.getAttribute("ldap_dnmgr")+"," +beanldaphost.getAttribute("ldap_dnbase")); htEnv.put("DN_PWD", beanldaphost.getAttribute("ldap_dnpwd")); htEnv.put("DN_BASE", beanldaphost.getAttribute("ldap_dnbase")); htEnv.put("DN_RAIZ", beanldaphost.getAttribute("ldap_dnraiz")); htEnv.put("DN_CTX", beanldaphost.getAttribute("ldap_ctxfactory")); ctx.close(); } catch(Exception e) { e.printStackTrace(); } finally { if(initCtx != null) initCtx.close(); } return htEnv; } }

El método getEnvironment recogerá los valores que habíamos definido en nuestra

configuración JNDI que son información acerca del directorio LDAP, esto almacenado en

un tipo de dato Collection de Java que es Hashtable, para luego estar disponible la

conexión hacia el directorio LDAP, el que prepara los datos de conexión hacia este

directorio es el método getInstance que tendrá los datos recogidos en dos variables

globales de la clase de tipo private para que pueda ser utilizado en otros métodos de la

clase.

Irenio Luis Chagua Aduviri

Page 28: Articulo_LDAP

Directorio SDK para Java

7. Directorio SDK para Java Como se ha mencionado anteriormente acerca del acceso a un directorio LDAP desde

una aplicación empresarial, aquí implementaremos los métodos para el acceso, tales

como autenticación de cuentas de usuario, cambio de atributos, agregar atributos, quitar

atributos, buscar mediante un RDN, entre otros.

Un directorio SDK para Java tiene las siguientes funcionalidades:

Libertad para el manejo de protocolos

El uso de objetos estándares para devolver y procesar los datos

Utilidad de clases para el manejo de las entidades específicas de LDAP

Acceso completo para todos los servicios LDAP

Modelos de autenticación flexibles

La habilidad de ejecutar en cualquier parte una vez se haya escrito el código

Funcionalidad multicapa

Una plataforma de aplicaciones para directorios

Búsqueda de una Entrada de Directorio Debido a que la facilidad de un directorio LDAP es su habilidad de mostrar resultados

de las consultas en forma rápida, para esto empezaremos con realizar una búsqueda

para obtener una entrada de nombre y sus atributos con sus respectivos valores.

Antes de realizar una búsqueda en un directorio LDAP, es necesario tener en cuenta la

siguiente información:

Nombre de Servidor donde está instalado el directorio LDAP, también puede ser la

dirección IP del servidor, se usa "localhost" cuando se realizan las pruebas en una

sola máquina.

Número de puerto del directorio LDAP, que es el puerto TCP de la máquina donde el

servidor de directorio es escuchado por las conexiones LDAP, el puerto estándar

para LDAP es 389 para las conexiones no SSL. Para las conexiones basados en SSL

es el puerto 636.

DN base del árbol de directorio administrado por el servidor, es el nombre base

como raíz por donde empezará a realizar la búsqueda, por ejemplo

ou=People,dc=nspsac,dc=com. Alcance de la búsqueda (Scope), es el punto de partida de una búsqueda y la

profundidad a la que realiza la búsqueda en un árbol de directorio, hay tres opciones

para este alcance:

o BASE, representado por la constante LDAPConnection.SCOPE_BASE, es usado

solo para búsquedas de DN base.

o ONE, representado por la constante LDAPConnection.SCOPE_ONE, es usado para

indicar que realice la búsqueda de todas las entradas debajo de DN base,

pero no incluye el DN base.

Irenio Luis Chagua Aduviri

Page 29: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

o SUBTREE, representado por la constante LDAPConnection.SCOPE_SUB, es

usado para indicar que realice la búsqueda de todas las entradas debajo e

incluso el DN base.

"(&(objectclass=person)(uid=" + uid + "))"

Filtros de búsqueda, es la consulta que se realiza, es usado para filtrar las entradas

de directorios y devolver cierta cantidad de registros. Los filtros son usados

mediante los paréntesis y combinaciones de los símbolos ‘&’, ‘|’ y ‘!’ que

representan ‘And’, ‘Or’ y ‘Not’ respectivamente. Si se quiere ubicar a todas las

personas que sus apellidos (representado mediante el atributo sn) empiecen con

“Mamani" se realiza mediante el siguiente filtro:

(&(objectclass=person)(sn=Mamani*))

Los atributos que se quieren mostrar en la búsqueda, puede que a veces solo se

requiere algunos atributos y no todos los atributos presentes en una entrada de

directorio. Si no se quiere recuperar ningún atributo se puede usar la constante

LDAPConnection.NO_ATTRS. Si se desea recibir todos los atributos del usuario se

puede usar la constante LDAPConnection.ALL_USER_ATTRS, ó en otro caso puede usar

un array de cadenas de caracteres indicando los atributos que se quiere recuperar.

Opcionalemente las preferencias de búsqueda, estas preferencias incluyen la

cantidad de tiempo que se desea permitir para la búsqueda, máximo número de

registros que se aceptará, y si la búsqueda debe esperar hasta que todos los datos

son recibidos. Las preferencias de búsqueda son especificados usando la clase

LDAPSearchConstraints. Los métodos usados en esta clase son las siguientes:

o setBatchSize especifica cómo deben ser devueltos los resultados de la

búsqueda. El valor cero ‘0’ indica que debe esperar hasta que todos los

resultados sean devueltos, el valor uno ‘1’ devuelve cada resultado como

esté disponible.

o setHopLimit especifica cuántas veces deben ser devueltas en una búsqueda

de una entrada.

o setMaxResults especifica el número máximo de resultados que deben ser

devueltas desde una búsqueda. Se usa el valor cero ‘0’ para resultados

ilimitados.

o setReferrals especifica si el SDK debe ó no seguir las referencias

automáticamente.

o setServerTimeLimit especifica el número máximo de segundos que debe

tardar en entregar los resultados de la búsqueda.

Una vez repasado sobre los conceptos para el acceso a un directorio LDAP, ahora

definimos el método que realizará la búsqueda en un directorio mediante un filtro que le

pasaremos como parámetro, este filtro será de tipo “atributo=valor”, que nos puede

servir para realizar búsquedas por los atributos uid, employeeNumber, ruc, dni, mail,

cn, sn y de los demás atributos, siempre y cuando el atributo sea de tipo cadena de

texto. El método tiene el nombre de buscarEnLDAP(String uid).

Para la búsqueda, ya contamos con información del nombre del servidor, el puerto del

servidor, el DN base, los atributos que están definidos en la variable ATTRS, y las

preferencias de búsqueda se ha establecido a un número máximo de registro igual a 1,

ya que la búsqueda está pensado para los atributos como nombres distintivos relativos y

Irenio Luis Chagua Aduviri

Page 30: Articulo_LDAP

Directorio SDK para Java

para obtener un conjunto de registros habría que cambiar estas preferencias de

búsqueda.

Los resultados de una búsqueda son devueltos como un objeto LDAPSearchResults. Hay

dos métodos para realizar el recorrido: nextElement y next, ambos métodos devuelven

un objeto que puede ser LDAPEntry, LDAPReferralException ó LDAPException. Para este

caso usaremos el método next.

El método next() de LDAPSearchResults devuelve un objeto LDAPEntry. La clase

LDAPEntry contiene los siguientes cuatro métodos:

getDN que devuelve el nombre distintivo completo de una entrada como una cadena

de texto (por ejemplo, uid=jmamani, ou=People, dc=nspsac, dc=com).

getAttribute(String name) en este caso el argumento es el nombre del atributo, del

que se quiere es su valor respectivo, es devuelto del tipo LDAPAttribute.

getAttributeSet devuelve un objeto LDAPAttributeSet que representa todos los

atributos en esta entrada.

toString devuelve la entrada completa, incluye los atributos obtenidos como una

cadena de texto.

Una vez que se tiene los atributos de una entrada, se puede obtener los valores de

estos atributos. La clase LDAPAttribute tiene varios métodos obtener el valor de los

atributos. Los métodos que normalmente se utilizan en la mayoría de los casos son los

siguientes:

getStringValues devuelve de tipo Enumeration los valores para un atributo de tipo

cadena de texto.

getByteValues devuelve de tipo Enumeration los valores para un atributo de tipo

binario, como el caso de las fotos.

getName devuelve el nombre del atributo.

private HashMap buscarEnLDAP(String uid) throws IncompleteConversationalState { HashMap hMap = new HashMap(); LDAPConnection ldap = new LDAPConnection(); try { ldap.connect(3, (String)htEnv.get("DN_HOST"), Integer.parseInt((String)htEnv.get("DN_PORT")), (String)htEnv.get("DN_MGR"), (String)htEnv.get("DN_PWD")); LDAPSearchConstraints mySearchConstraints = ldap.getSearchConstraints(); mySearchConstraints.setMaxResults(1); LDAPSearchResults myResults = null; myResults = ldap.search( new StringBuffer( (String)htEnv.get("DN_RAIZ")).append(", ").append( (String)htEnv.get("DN_BASE")).toString(), LDAPv3.SCOPE_SUB, "(&(objectclass=person)(" + uid + "))", ATTRS, false, mySearchConstraints); if (myResults.hasMoreElements()) { LDAPEntry myEntry = myResults.next(); hMap.put("dn", myEntry.getDN());

Irenio Luis Chagua Aduviri

Page 31: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

LDAPAttributeSet entryAttrs = myEntry.getAttributeSet(); Enumeration attrsInSet = entryAttrs.getAttributes(); String namePhoto = ((String)myEntry.getAttribute("uid"). getStringValues().nextElement()).concat(".jpg"); while (attrsInSet.hasMoreElements()) { LDAPAttribute nextAttr = (LDAPAttribute) attrsInSet.nextElement(); String attrName = nextAttr.getName(); if (attrName.trim().equalsIgnoreCase("jpegPhoto")) { Enumeration valsInAttr = nextAttr.getByteValues(); if (valsInAttr.hasMoreElements()) { if(savePhoto(namePhoto, (byte[])valsInAttr.nextElement())){ hMap.put(attrName.trim(), namePhoto); } else { hMap = new HashMap(); hMap.put("Mensaje","Error al recuperar Foto"); break; } } } else{ Enumeration valsInAttr = nextAttr.getStringValues(); if (valsInAttr.hasMoreElements()) { hMap.put(attrName.trim(), valsInAttr.nextElement()); } } } } else{ hMap.put("Mensaje","El Usuario indicado no se encuentra registrado."); } } catch (LDAPException e) { e.printStackTrace(); hMap.put("Mensaje","ERROR:" +e.getLDAPResultCode() +"->" +LDAPException.errorCodeToString(e.getLDAPResultCode())); } catch (NumberFormatException e) { e.printStackTrace(); hMap.put("Mensaje", "HA OCURRIDO UN PROBLEMA EN LOS PARAMETROS DEL SERVIDOR:" + e.getMessage()); } finally { try { if (ldap.isConnected()) { ldap.disconnect(); } } catch L Exception ex) { ( DAP throw new IncompleteConversationalState( "NO SE PUDO CERRAR EL ENLACE:" + ex.getLDAPResultCode() + "->" + LDAPException.errorCodeToString(ex.getLDAPResultCode())); } } return hMap; }

Irenio Luis Chagua Aduviri

Page 32: Articulo_LDAP

Directorio SDK para Java

private boolean savePhoto(String namePhoto, byte[] thePhoto){ boolean saved = false; try{ OutputStream outputStream = new FileOutputStream(DIR_IMGS+namePhoto); outputStream.write(thePhoto); outputStream.flush(); outputStream.close(); saved = true; } catch (FileNotFoundException e){ e.printStackTrace(); } catch (IOException e){ e.printStackTrace(); } return saved; }

Autenticando Usuarios Hasta aquí no hemos visto el tema de autenticación a un directorio LDAP. Las

conexiones hasta aquí han sido utilizando la cuenta por defecto configurado en el mismo

directorio LDAP, más no hemos utilizado la cuenta de usuario y su contraseña. Por

ejemplo es posible que en un directorio se quiera restringir el acceso a ciertos

atributos, no permitiendo el acceso a algunos atributos como la fotografía de un

empleado, que solamente puede tener acceso personal autorizado. Para realizar

cambios tales como agregar, modificar, consultar ó eliminar ciertos atributos de una

entrada de directorio LDAP, por lo general se debe autenticar.

El protocolo LDAP proporciona una operación para permitir conectar a los clientes para

autenticar al servidor. El método más simple de autenticación soportado por el

protocolo es un método que al cliente le permite enviar un DN y contraseña al servidor.

Para usar el método de autenticación simple, se puede usar mediante el método

LDAPConnection.authenticate ó un método LDAPConnection.connect variante que toma una

autenticación pasando como parámetros a DN y contraseña. Algunas de las excepciones

que se pueden producir son las siguientes:

LDAPException.NO_SUCH_OBJECT. Esta excepción es lanzada si el DN especificado no

corresponde a una entrada del directorio.

LDAPException.INVALID_CREDENTIALS. Esta excepción es lanzada si la contraseña

especificado no es correcta.

public HashMap autenticar(String uid, String pwd) throws NamingException, IncompleteConversationalState { HashMap hMap = new HashMap(); LDAPConnection ldap = new LDAPConnection(); try { ldap.connect(3, (String)htEnv.get("DN_HOST"), Integer.parseInt((String)htEnv.get("DN_PORT")), (String)htEnv.get("DN_MGR"), (String)htEnv.get("DN_PWD")); hMap = buscarEnLDAP("uid=" + uid); if(hMap.get("dn") != null){ ldap.authenticate( (String) hMap.get("dn"), pwd);

Irenio Luis Chagua Aduviri

Page 33: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

} if(hMap.get("Mensaje") == null){ hMap.put("Mensaje","Usuario ".concat(uid).concat(" autenticado")); } } catch (LDAPException e) { e.printStackTrace(); hMap = new HashMap(); switch (e.getLDAPResultCode()) { case LDAPException.NO_SUCH_OBJECT: hMap.put("Mensaje",uid.concat(": El usuario indicado no existe")); break; case LDAPException.INVALID_CREDENTIALS: hMap.put("Mensaje",uid.concat(": Password invalido")); break; default: hMap.put("Mensaje",uid.concat( ": No se ha podido realizar la autenticacion, error:" + e.getLDAPResultCode())); break; } } catch (NumberFormatException e) { e.printStackTrace(); hMap = new HashMap(); hMap.put("Mensaje", "HA OCURRIDO UN PROBLEMA EN LOS PARAMETROS DEL SERVIDOR:" + e.getMessage()); } finally { try { if (ldap.isConnected()) { ldap.disconnect(); } } catch (LDAPException ex) { throw new IncompleteConversationalState( "NO SE PUDO CERRAR EL ENLACE:" + ex.getLDAPResultCode() + "->" + LDAPException.errorCodeToString(ex.getLDAPResultCode()) + "<br>" + ex.getMessage()); } } return hMap; }

Creando y Manipulando entradas de directorio En una entrada de directorio LDAP es posible realizar las modificaciones de una

entrada, tanto en crear una entrada, modificar una entrada con sus respectivos

atributos, y eliminar una entrada. En la modificación de entradas es posible el manejo de

los atributos como la de añadir atributos, modificar atributos y eliminar atributos. Estas

operaciones siempre estarán presentes en un manejo de entrada de directorios LDAP.

Irenio Luis Chagua Aduviri

Page 34: Articulo_LDAP

Directorio SDK para Java

Para agregar una nueva entrada de directorio es necesario definir un nombre distintivo

DN para la entrada y los atributos para esta entrada. Para agregar una nueva entrada es

necesario tener en cuenta los siguientes pasos:

1. Crear un objeto LDAPAttribute para cada atributo que forma la entrada.

2. Crear un objeto LDAPAttributeSet y utilizar el método add para agregar cada objeto

LDAPAttribute del paso 1.

3. Crear un objeto LDAPEntry que especifica el nuevo DN y el LDAPAttributeSet del

paso 2.

4. Invocar al método LDAPConnection.add con el objeto LDAPEntry del paso 3.

Con estos pasos se ha creado el método addEntry que recibe dos parámetros, el primero

es el nombre distintivo identificador de usuario y el segundo un conjunto de atributos en

un Collection HashMap.

public void addEntry(String uid, HashMap attrs) { LDAPAttributeSet entryAttrs = new LDAPAttributeSet(); LDAPConnection ldap = new LDAPConnection(); try{ ldap.connect(3, (String)htEnv.get("DN_HOST"), Integer.parseInt((String)htEnv.get("DN_PORT")), (String)htEnv.get("DN_MGR"), (String)htEnv.get("DN_PWD")); String dn = new StringBuffer("uid=").append(uid).append(", ").append( (String)htEnv.get("DN_RAIZ")).append(", ").append( (String)htEnv.get("DN_BASE")).toString(); for(Iterator it = attrs.keySet().iterator(); it.hasNext(); ){ String name = (String)it.next(); entryAttrs.add( new LDAPAttribute( name, (String)attrs.get(name))); } entryAttrs.add( new LDAPAttribute("objectClass", OBECT_CLASS) ); LDAPEntry myEntry = new LDAPEntry( dn, entryAttrs ); ldap.add(myEntry); } catch (LDAPException e) { e.printStackTrace(); } }

La otra operación con las entradas es la modificación de sus atributos. Para modificar

un atributo de una entrada, se ha utilizado el método modifyAttributes del objeto

DirContext, también es posible modificar un atributo con el uso del objeto

LDAPModification y luego invocando al método modify de LDAPConnection. Para modificar

los atributos de una entrada es necesario tener en cuenta los siguientes pasos:

1. Crear un objeto Attribute para un atributo que se desea modificar.

2. Crear un conjunto de objetos ModificationItem, puede ser uno solo, especificando

DirContext.ADD_ATTRIBUTE, REPLACE_ATTRIBUTE ó REMOVE_ATTRIBUTE para cada objeto

Attribute del paso 1.

3. Invocar al método modifyAttributes con el DN y el ModificationItem.

Irenio Luis Chagua Aduviri

Page 35: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

public void addAttribute(String uid, String nameAttr, String valAttr) throws NamingException { ModificationItem[] mods = new ModificationItem[1]; Attribute mod = new BasicAttribute(nameAttr, valAttr); mods[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE, mod); String dn = new StringBuffer("uid=").append(uid).append(", ").append( htEnv.get("DN_RAIZ")).append(",").append( htEnv.get("DN_BASE")).toString(); nspsacCtx.modifyAttributes(dn, mods); } public void modifyAttribute(String uid, String nameAttr, String valAttr) throws NamingException { ModificationItem[] mods = new ModificationItem[1]; Attribute mod = new BasicAttribute(nameAttr, valAttr); mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, mod); String dn = new StringBuffer("uid=").append(uid).append(", ").append( htEnv.get("DN_RAIZ")).append(",").append( htEnv.get("DN_BASE")).toString(); nspsacCtx.modifyAttributes(dn, mods); } public void deleteAttribute(String uid, String nameAttr) throws NamingException { ModificationItem[] mods = new ModificationItem[1]; Attribute mod = new BasicAttribute(nameAttr); mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, mod); String dn = new StringBuffer("uid=").append(uid).append(", ").append( htEnv.get("DN_RAIZ")).append(",").append( htEnv.get("DN_BASE")).toString(); nspsacCtx.modifyAttributes(dn, mods); }

Los datos de una entrada deben estar bien guardados en un directorio LDAP. Pero llega

un momento en que será necesario borrar una entrada LDAP. Para esto quitar una

entrada de un directorio es muy simple. Solamente se debe especificar qué DN se debe

quitar e invocar al método LDAPConnection.delete.

public void deleteEntry(String uid) { LDAPConnection ldap = new LDAPConnection(); try{ ldap.connect(3, (String)htEnv.get("DN_HOST"), Integer.parseInt((String)htEnv.get("DN_PORT")), (String)htEnv.get("DN_MGR"), (String)htEnv.get("DN_PWD")); String dn = new StringBuffer("uid=").append(uid).append(", ").append( (String)htEnv.get("DN_RAIZ")).append(", ").append( (String)htEnv.get("DN_BASE")).toString(); ldap.delete(dn); } catch (LDAPException e) { e.printStackTrace(); } }

Irenio Luis Chagua Aduviri

Page 36: Articulo_LDAP

Directorio SDK para Java

Por último, la operación en una entrada es el renombramiento, es decir modificando el

RDN de una entrada de directorio LDAP. Por ejemplo se puede cambiar uid=pcarrillo

del DN ou=People,dc=nspsac,dc=com para tener el uid=pedro.carrillo del DN

ou=People,dc=nspsac,dc=com. El método LDAPConnection.rename invoca la operación LDAP

para cambiar el RDN de la entrada.

No solamente es posible cambiar el RDN en un mismo nivel del árbol del directorio

LDAP, hay la posibilidad de mover ó copiar a un RDN a una parte diferente del árbol del

directorio LDAP. Como ejemplo veamos al RDN uid=jmamani del DN

ou=People,dc=nspsac,dc=com lo movemos ó lo copiamos a otra parte del árbol como RDN

uid= juan.mamani y DN ou=Admin,dc=nspsac,dc=com.

public void renameEntry(String uid, String newUid) { LDAPConnection ldap = new LDAPConnection(); try{ ldap.connect(3, (String)htEnv.get("DN_HOST"), Integer.parseInt((String)htEnv.get("DN_PORT")), (String)htEnv.get("DN_MGR"), (String)htEnv.get("DN_PWD")); String dn = new StringBuffer("uid=").append(uid).append(", ").append( (String)htEnv.get("DN_RAIZ")).append(", ").append( (String)htEnv.get("DN_BASE")).toString(); String newRDN = new StringBuffer("uid=").append(newUid).toString(); ldap.rename(dn, newRDN, true); } catch (LDAPException e) { e.printStackTrace(); } } public void renameEntry(String uid, String newUid, String newGroup) { LDAPConnection ldap = new LDAPConnection(); try{ ldap.connect(3, (String)htEnv.get("DN_HOST"), Integer.parseInt((String)htEnv.get("DN_PORT")), (String)htEnv.get("DN_MGR"), (String)htEnv.get("DN_PWD")); String dn = new StringBuffer("uid=").append(uid).append(", ").append( (String)htEnv.get("DN_RAIZ")).append(", ").append( (String)htEnv.get("DN_BASE")).toString(); String newRDN = new StringBuffer("uid=").append(newUid).toString(); String newParentDN = new StringBuffer("ou=").append(newGroup).append(", ").append((String)htEnv.get("DN_BASE")).toString(); ldap.rename(dn, newRDN, newParentDN, true); } catch (LDAPException e) { e.printStackTrace(); } }

Irenio Luis Chagua Aduviri

Page 37: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

Servlets, JSP y LDAP Una vez que se ha realizado con la implementación de las clases para el acceso a un

directorio LDAP, será necesario mostrar el resultado del acceso mediante un Servlet

para enviar datos a una página web haciendo uso de JSP. Para esto creamos el Servlet

ServletGestionLDAP.

package com.nspsac.seguridad; import java.util.HashMap; import javax.naming.NamingException; import javax.servlet.ServletException; import javax.servlet.ServletConfig; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.nspsac.seguridad.ldap.AccesoLDAP; import com.nspsac.seguridad.ldap.AccesoLDAPFactory; import com.nspsac.utils.exception.IncompleteConversationalState; public class ServletGestionLDAP extends HttpServlet{ public void init(ServletConfig config) throws ServletException { super.init(config); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { HashMap hmAut = null; HashMap hmSearch = null; String cambioClave = null; HttpSession session = request.getSession(true); try{ String accion = request.getParameter("accion"); String opcion = request.getParameter("modo"); AccesoLDAP acceso = AccesoLDAPFactory.create(); acceso.getInstance(); String usuario = request.getParameter("user"); if(accion.equals("autenticacion")){ String clave = request.getParameter("pwd"); hmAut = acceso.autenticar(usuario,clave); session.setAttribute("hmAut", hmAut); session.removeAttribute("hmSearch"); session.removeAttribute("cambioClave"); } else if(accion.equals("busqueda")){ hmSearch = acceso.findByUID(usuario); session.setAttribute("hmSearch", hmSearch); session.removeAttribute("hmAut"); session.removeAttribute("cambioClave"); } else if(accion.equals("cambioclave")){ String claveanterior = request.getParameter("oldpwd"); String clavenueva = request.getParameter("newpwd"); String claveconfirma = request.getParameter("repwd"); cambioClave = usuario.concat(": Usuario indicado no existe."); if(clavenueva.equals(claveconfirma)){ acceso.cambiarClave(usuario,claveanterior,clavenueva); cambioClave = usuario.concat(": La clave ha sido clambiada

Irenio Luis Chagua Aduviri

Page 38: Articulo_LDAP

Directorio SDK para Java

satisfactoriamente."); } else{ cambioClave = usuario.concat(": Clave nueva y su confirmaci&oacute;n no concuerdan."+ "<br>Ingresar nuevamente las claves"); } session.setAttribute("cambioClave", cambioClave); session.removeAttribute("hmAut"); session.removeAttribute("hmSearch"); } session.setAttribute("opcion", opcion); HashMap hmAttrs = new HashMap(); hmAttrs.put("givenName", "Alberto"); hmAttrs.put("sn","Velasquez Prado"); hmAttrs.put("mail","[email protected]"); hmAttrs.put("uid","avelasquez"); hmAttrs.put("cn","Alberto Velasquez Prado"); hmAttrs.put("dni","87654321"); hmAttrs.put("ruc","10876543218"); hmAttrs.put("employeeNumber","6825"); hmAttrs.put("telephoneNumber","051202020"); hmAttrs.put("direccion","Av. El Sol Nro. 560"); hmAttrs.put("st","Puno"); hmAttrs.put("l","Puno"); acceso.addEntry("avelasquez",hmAttrs); acceso.addAttribute("avelasquez","userPassword","abc"); acceso.modifyAttribute("avelasquez","userPassword","abc1"); acceso.renameEntry("pcarrillo","pedro.carrillo"); acceso.renameEntry("jmamani","juan.mamani","Admin"); } catch(NamingException ne){ ne.printStackTrace(); } catch(IncompleteConversationalState ics){ ics.printStackTrace(); } catch(Exception e){ e.printStackTrace(); } try{ getServletConfig().getServletContext().getRequestDispatcher("/ldap").forward(request, response); } catch(Exception e){ e.printStackTrace(); } } }

Irenio Luis Chagua Aduviri

Page 39: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

FIGURA 7.1 Pantalla de Inicio

La página JSP que recoge valores enviados desde un servlet como los atributos de una

entrada de directorio, son definidos de la siguiente forma.

<% HashMap hmAut = (HashMap)session.getAttribute("hmAut"); HashMap hmSearch = (HashMap)session.getAttribute("hmSearch"); String cambioClave = (String)session.getAttribute("cambioClave"); String opcion = (String)session.getAttribute("opcion"); %> <%//... Para mostrar los datos de una entrada después de autenticar...%> <%if(hmAut != null){ String uid = (String)hmAut.get("uid"); String sn = (String)hmAut.get("sn"); String givenName = (String)hmAut.get("givenName"); String cn = (String)hmAut.get("cn"); String employeeNumber = (String)hmAut.get("employeeNumber"); String dni = (String)hmAut.get("dni"); String ruc = (String)hmAut.get("ruc"); String direccion = (String)hmAut.get("direccion"); String mail = (String)hmAut.get("mail"); String telephoneNumber = (String)hmAut.get("telephoneNumber"); String mobile = (String)hmAut.get("mobile"); String jpegPhoto = (String)hmAut.get("jpegPhoto"); String msg = (String)hmAut.get("Mensaje"); if(msg != null){%> <div class="titulo"><%=msg%></div> <%}%> <table> <tr><td><b>Cuenta de Usuario :</b></td> <td><%=uid%></td></tr> <tr><td><b>Apellidos :</b></td> <td><%=sn%></td></tr> <tr><td><b>Nombres :</b></td> <td><%=givenName%></td></tr> <tr><td><b>Nombre Completo :</b></td> <td><%=cn%></td></tr> <tr><td><b>Registro Emplea </b></td> do : <td><%=(employeeNumber!=null?employeeNumber:"-")%></td></tr> <tr><td><b>DNI :</b></td> <td><%=dni%></td></tr> <tr><td><b>RUC :</b></td> <td><%=ruc%></td></tr> <tr><td><b>Dirección :</b></td> <td><%=direccion%> - <%=hmAut.get("l")%>, <%=hmAut.get("st")%></td></tr> <tr><td><b>Correo Electrónico :</b></td> <td><%=mail%></td></tr> <tr><td><b>Teléfono :</b></td> <td><%=(telephoneNumber!=null)?telephoneNumber:"-"%></td></tr> <tr><td><b>Teléfono Móvil :</b></td> <td><%=(mobile!=null)?mobile:"-"%></td></tr> <tr> <td valign="top"><b>Foto :</b></td>

Irenio Luis Chagua Aduviri

Page 40: Articulo_LDAP

Directorio SDK para Java

<td> <%if(jpegPhoto != null) {%> <img src="imgs/<%=jpegPhoto%>" alt="" border="0" width="70" height="80"> <% } else {%> - <% }%> </td> </tr> </table> <%}%> <% ... Para most datos de una entrada después de una búsqueda... %> // rar <%if(hmSearch != null){ String msg = (String)hmSearch.get("Mensaje"); if(msg != null){%> <div class="titulo"><%=msg%></div> <% hmSearch.remove("Mensaje"); } for (Iterator it = hmSearch.keySet().iterator(); it.hasNext();){ String name = (String)it.next(); String value = (String)hmSearch.get(name); if(!name.equals("jpegPhoto")){%> <%=name%>: <%=value%><br> <%} else{ %> <%=name%>: <br><img src="imgs/<%=value%>" alt="" border="0"><br> <%} } }%>

Y por último realizando las búsquedas de entradas de directorios mediante un RDN,

autenticando usuarios y cambiando clave de un usuario. Solamente se ha incluido en la

página web las funcionalidades mencionadas, las demás opciones ya los puede incluir

con los métodos desarrollados en el presente artículo.

FIGURA 7.2 Usuario Autenticado

Irenio Luis Chagua Aduviri

Page 41: Articulo_LDAP

Acceso a OpenLDAP mediante Netscape Directory SDK

8. Directorios LDAP Apache Directory Server

OpenLDAP

Novell eDirectory

Windows Server 2003 Active Directory

Oracle Internet Directory

Sun Java System Directory Server Enterprise Edition

9. Clientes LDAP JXplorer (Java)

LDAP Browser/Editor (Java)

Luma (Unix)

Frood (Unix)

CoralDirectory LDAP Browser (Windows)

LDAP Exporter (Windows)

maX.500 Macintosh

phpLDAPadmin (web)

10. Librerías para LDAP Java LDAP

JDBC-LDAP Bridge Driver

Sun (iPlanet) Directory Server Deployment Guide

PHP LDAP

.NET LDAP

Perl-LDAP

Ruby/LDAP

Mozilla LDAP C SDK

LDAP in Python

11. Referencias y Herramientas utilizadas 1. OpenLDAP 2.2.29. http://www.openldap.org/

2. Netscape Directory SDK 4.1 for Java. http://www.mozilla.org/

3. JavaTM Platform, Standard Edition 6 Development Kit. http://java.sun.com/

4. Apache Jakarta Tomcat 5.5.9. http://www.apache.org/

5. LDAP Browser\Editor 2.8.2. http://www.iit.edu/~gawojar/ldap/

6. LDAP en Español. http://www.ldap-es.org/

7. Fuente de este artículo. http://www.javahispano.org/download/articulos/ldap.zip

Irenio Luis Chagua Aduviri