Preguntas sobre Contextos
¿Cuál es la relación entre un contexto y la conexión con el servidor LDAP?
Cuando creamos un
InitialContext,
InitialDirContext,
o un
InitialLdapContext
usando el proveedor de servicio LDAP, se configura inmediatamente una conexión con el servidor LDAP
objetivo. Todos los contextos y
NamingEnumerations
que se deriven de este contexto inicial comparten la misma conexión que el contexto inicial
Por ejemplo, si llamamos a
Context.lookup() o a
Context.listBindings() desde el contexto inicial y
obtenemos de vuelta otros contextos, entonces todos esos contextos compartirán la misma conexión.
Si creamos un nuevo contexto inicial, tendrá su propia conexión.
Cuando cambiamos las propiedades de entorno que están relacionadas con una conexión, como
el nombre o las credenciales del usuario, el contexto sobre el que hemos hecho esos cambios
obtendrá su propia conexión (si la conexión es compartida). Los contextos que desciendan de
este contexto en el futuro compartirán esta nueva conexión, pero aquellos que la compartían
anteriormente no se verán afectados (es decir, continuaran usando la vieja conexión).
De forma similar, si usamos
LdapContext.reconnect(), entonces el ejemplar
Context sobre el que llamamos a este método obtendrá su propia
conexión si la conexión era compartida.
¿Cómo cierro la conexión con el servidor LDAP?
Para cerrar la conexión con el servidor, llamamos a Context.close()
sobre todos los contextos originarios del contexto inicial que creó la conexión.
Debemos asegurarnos de que se ha completado toda la NamingEnumeration.
Para aquellos contextos y objetos enumeración que no van a permanecer más en el ámbito, el sistema
de ejecución Java los recolectará como basura eventualmente, así generará el estado de limpieza que un
close() habría hecho. Para forzar la recolección de basura, podemos
usar el siguiente codigo:
Runtime.getRuntime().gc();
Runtime.getRuntime().runFinalization();
¿Es el contexto seguro para acceso multi-thread, o necesito bloquear/sincronizar los accesos
al contexto?
La respuesta depende de la implementación. Esto es así porque los interfaces
Context y
DirContext no especifican requerimientos de sincronización.
La implementación LDAP de Sun está optimizada para accesos de un sólo thread. Si tenemos varios threads
accediendo al mismo ejemplar Context, cada thread necesita bloquear el
Context cuando lo usa. Esto se aplica a cualquier
NamingEnumeration que descienda del mismo ejemplar
Context. Sin embargo, múltiples threads pueden acceder a diferentes
ejemplares de Context (incluso aquellos que descienden del mismo contexto
inicial) sin bloqueos concurrentes.
¿Por qué el proveedor LDAP ignora mis propiedades de entorno de seguridad si no configuro
la propiedad
Context.SECURITY_CREDENTIALS (
"java.naming.security.credentials") o la configuro con una cadena vacía?
Si suministramos una cadena vacía, un byte/char
vacío, o null a la propiedad de entorno
Context.SECURITY_CREDENTIALS, ocurrirá una unión anónima incluso si la
propiedad Context.SECURITY_AUTHENTICATION fue configurada como
"simple". Esto es porque para la autentificación "simple", el LDAP requiere
que las passwords no estén vacías. Si no se suministra una password, el protocole convierte automáticamente
la autentificación a "none".
¿Por qué sigo obteniendo un
CommunicationException cuando intento crear un contexto
inicial?
Podrías estar hablando con un servidor que sólo soporta LDAP v2. En la lección
Miscelánea puedes ver un ejemplo de cómo configurar
el número de versión.
¿Estoy viendo un comportamiento extraño. ¿Cómo puedo saber lo que está ocurriendo realmente?
Intenta usar la propiedad de entorno "com.sun.jndi.ldap.trace.ber".
Si el valor de esta propiedad es un ejemplar de java.io.OutputStream,
la información de trazado sobre los buffers BER envíada y recibida desde el proveedor LDAP se escribe
en ese stream. Si el valor de la propiedad es null, no se escribirá
salida de trazado.
Por ejemplo, el siguiente codigo enviára la salida de trazado a System.err:
env.put("com.sun.jndi.ldap.trace.ber", System.err);
¿Cómo uso un mecanismo de autentificación diferente, como Kerberos?
Primero, necesitamos tener las clases Java que soportan Kerberos y/o GSSAPI. Luego, necesitamos
seguir las instrucciones de la lección
Securidad para poner diponible una
implementación de un mecanismo SASL para el proveedor LDAP.