Almacenamiento de objetos Java en Active Directory utilizando LDAP y JNDI

...

En esta entrada se describen los pasos que deben llevarse a cabo para almacenar objetos Java en Microsoft Active Directory utilizando el protocolo LDAP.

Motivación

Incluso hoy -en tiempos de la "Nube"- las organizaciones con operaciones descentralizadas suelen requerir el desarrollo y el mantenimiento de sistemas distribuidos.

En estos casos, el mantenimiento de información consistente en todos las ubicaciones suele ser un issue a resolver, sin embargo, las organizaciones cuentan con una herramienta fiable y consistente para llevar a cabo esta tarea: Microsoft Active Directory (AD).

Aunque podemos afirmar que la mayoría de las empresas que requieren soluciones distribuidas tienen implementaciones de AD en su infraestructura, rara vez extienden su utilización a la esfera de las aplicaciones de negocio mas allá del proceso de autenticación y/o autorización de los usuarios.

Es importante que la utilización de Active Directory para almacenar objetos se lleve a cabo con criterio, es un directorio, no una base de datos relacional; por ejemplo, se puede almacenar información de ubicación de servicios, información de negocio que no cambia constantemente, etc.

Configuración de AD para almacenar objetos Java

El servicio de AD requiere de una configuración adicional para soportar el RFC 2713 que establece como se deben almacenar objetos Java en un directorio LDAP. El RFC 2713 es un esquema que define los elementos necesarios para representar objetos Java serializados y remotos en un directorio LDAP.

Oracle proporciona la clase CreateJavaSchema para configurar el esquema necesario para almacenar objetos Java en un directorio LDAP.

Una vez que compilamos la clase será necesario ejecutar el siguiente comando indicando el host correspondiente al AD y las credenciales de acceso:


java    -Djava.naming.provider.url=ldap://AD_HOST_OR_IP CreateJavaSchema 
        -sad 
        -nUSERNAME 
        -pPASSWORD

Por ejemplo:

java    -Djava.naming.provider.url=ldap://ad.intra.microgestion.com CreateJavaSchema 
        -sad 
        -nCN=Administrator,CN=Users,DC=intra,DC=microgestion,DC=com 
        -pMiAdminPassword

El resultado de la ejecución debería ser similar al siguiente:

[updating Active Directory schema ...]
  [locating the schema]
  [inserting new attribute definitions ...]
    [javaClassName]
    [javaCodeBase]
    [javaSerializedData]
    [javaFactory]
    [javaReferenceAddress]
    [javaDoc]
    [javaClassNames]
  [inserting new object class definitions ...]
    [javaContainer]
    [javaObject]
    [javaSerializedObject]
    [javaNamingReference]
    [javaMarshalledObject]
[update completed]
Use your directory server's administration tool to verify
that the schema is correct:

Acerca de JNDI y el almacenamiento de objetos en AD

Java Naming Directory Interface, o JNDI, es una API de Java que proporcionar una visión orientada a objetos de un directorio o servicio de nombres; los servicios accesibles mediante el protocolo LDAP -en nuestro caso Active Directory- entran dentro de esta categoría y por ello son accesibles mediante JNDI.

El acceso a un directorio utilizando JNDI se realiza mediante contextos. Los contextos son conjuntos de enlaces a objetos que se pueden crear y luego encontrar a través de operaciones de búsqueda o resolución de nombres.

El siguiente fragmento de código crea un contexto para acceder a un AD utilizando el protocolo LDAP:


String baseDN = ",DC=intra,DC=microgestion,DC=com";
java.util.Properties properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
properties.setProperty(Context.PROVIDER_URL, "ldap://ad.intra.microgestion.com/OU=JAVA" + baseDN);
properties.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
properties.setProperty(Context.SECURITY_PRINCIPAL, "CN=Administrator,CN=Users" + baseDN );
properties.setProperty(Context.SECURITY_CREDENTIALS, "MiAdminPassword");
javax.naming.Context context = new javax.naming.InitialContext(properties);

Nota: es conveniente almacenar los objetos Java en un contenedor del directorio dedicado para este fin, en nuestro caso, como se puede ver al establecer el valor de la propiedad Context.PROVIDER_URL, utilizaremos una unidad organizacional denominada JAVA, cuyo nombre distinguido es OU=JAVA,DC=intra,DC=microgestion,DC=com.

Almacenamiento, lectura y eliminación de objectos serializables

Cuando almacenamos un objeto dentro de un directorio, conceptualmente, estamos creando un enlace; la clase javax.naming.Context dispone de un método denominado bind que permite llevar a cabo esta tarea tal como se muestra en el siguiente fragmento de código en donde se almacena un objeto del tipo String con el nombre MiObjeto:


java.util.Properties properties = new Properties();
...
javax.naming.Context context = new javax.naming.InitialContext(properties);
String objectName = "MiObjeto";
String object = "Objeto del tipo java.lang.String";
context.bind("cn=" + objectName, object);

Con la ayuda de una herramienta de visualización de directorios LDAP es posible observar la representación del objeto almacenado en el directorio:

Atributos del objeto almacenado en AD

La lectura de un objeto almacenado se realiza por medio del método lookup de la clase javax.naming.Context, el siguiente ejemplo muestra como eliminar el objeto creado anteriormente:

java.util.Properties properties = new Properties();
...
javax.naming.Context context = new javax.naming.InitialContext(properties);
String objectName = "MiObjeto";
String object = (String) context.lookup("cn=" + objectName);
System.out.println(object);

Para eliminar un objeto almacenado tendremos que utilizar el método unbind de la clase javax.naming.Context, el siguiente ejemplo muestra como eliminar el objeto creado anteriormente:

java.util.Properties properties = new Properties();
...
javax.naming.Context context = new javax.naming.InitialContext(properties);
String objectName = "MiObjeto";
context.unbind("cn=" + objectName);

Referencias


Modificado por última vez en Lunes, 18 Noviembre 2013 14:11

Acerca del autor

Diego E. Mendoza

Diego se desempeña como arquitecto de software en MicroGestion participando en el proceso de análisis y diseño de soluciones que tengan requerimientos de alta disponibilidad, integración de ambientes heterogéneos, orientación a servicios, gestión de procesos de negocio, etc.