java - Tomcat 8-LDAP: Código de error de excepción NameNotFoundException 32, nombre restante cadena vacía
weblogic tomcat8 (1)
El stacktrace se fue agregando a la propiedad java.naming.provider.url
el DN del esquema LDAP, utilizando la primera implementación de fábrica provista en la pregunta.
A continuación, se muestra una captura de pantalla del cliente LDAP utilizado en este contexto, el Apache Directory Studio / LDAP Browser integrado en Eclipse, desde el cual fue posible explorar el LDAP en cuestión simplemente usando los valores iniciales de la pregunta.
Al agregar el esquema DN del elemento raíz a la URL de conexión, la excepción desapareció y el recurso LDAP ahora se comparte a través de JNDI en Tomcat 8.
Más detalles como resultado de la solución de problemas :
En Tomcat 8, los recursos globales se manejan a través de una escucha de recursos global, GlobalResourcesLifecycleListener
, definida de forma predeterminada en el archivo server.xml
. Un oyente de este tipo here un context.listBindings("")
en la creación del bean, por lo tanto, busca el directorio LDAP.
Esta exploración inicial probablemente sea la diferencia entre Tomcat y WebLogic, donde LDAP se busca a través de JNDI solo cuando es necesario, por lo tanto, a través de una consulta directa, en lugar de iniciar con una consulta genérica. Como tal, en Tomcat, la URL de LDAP necesitaría más detalles, es decir, una configuración ligeramente diferente como parte de su URL para apuntar directamente a un DN de base válido.
De la documentación oficial de WebLogic :
Al iniciarse, WebLogic Server intenta conectarse a la fuente JNDI. Si la conexión es exitosa, WebLogic Server configura los objetos y enlaces solicitados en el árbol JNDI local, haciéndolos disponibles para los clientes de WebLogic Server.
Por lo tanto, una conexión es bastante más simple que un listBindings
:
Enumera los nombres enlazados en el contexto nombrado, junto con los objetos vinculados a ellos. Los contenidos de cualquier subcontexto no están incluidos.
Al intentar migrar una aplicación de WebLogic 12.2.1 a Tomcat 8.5.4 , lo que en Weblogic era una entrada como proveedores extranjeros JNDI para una conexión LDAP se ha migrado a un nuevo Resource
en Tomcat.
Siguiendo este consejo sobre el desbordamiento de pila, se ha empaquetado un LdapContextFactory
personalizado como un nuevo archivo jar
en la carpeta lib
Tomcat.
En el archivo server.xml
Tomcat, se han configurado los siguientes GlobalNamingResources/Resource
:
<Resource name="ldapConnection"
auth="Container"
type="javax.naming.ldap.LdapContext"
factory="com.sample.custom.LdapContextFactory"
singleton="false"
java.naming.referral="follow"
java.naming.factory.initial="com.sun.jndi.ldap.LdapCtxFactory"
java.naming.provider.url="ldap://some.host:389"
java.naming.security.authentication="simple"
java.naming.security.principal="CN=some,OU=some,OU=some,DC=some,DC=a,DC=b"
java.naming.security.credentials="password"
com.sun.jndi.ldap.connect.pool="true"
com.sun.jndi.ldap.connect.pool.maxsize="10"
com.sun.jndi.ldap.connect.pool.prefsize="4"
com.sun.jndi.ldap.connect.pool.timeout="30000" />
La conexión anterior funciona bien cuando se navega por el directorio LDAP a través de un navegador LDAP como Apache Directory Studio / LDAP Browser integrado en Eclipse.
El com.sample.custom.LdapContextFactory
personalizado es bastante simple:
public class LdapContextFactory implements ObjectFactory {
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment)
throws Exception {
Hashtable<Object, Object> env = new Hashtable<>();
Reference reference = (Reference) obj;
Enumeration<RefAddr> references = reference.getAll();
while (references.hasMoreElements()) {
RefAddr address = references.nextElement();
String type = address.getType();
String content = (String) address.getContent();
env.put(type, content);
}
return new InitialLdapContext(env, null);
}
}
Sin embargo, al inicio, Tomcat está lanzando la siguiente excepción:
07-Sep-2016 15:04:01.064 SEVERE [main] org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans Exception processing Global JNDI Resources
javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-031001E5, problem 2001 (NO_OBJECT), data 0, best match of:
''''
]; remaining name ''''
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3160)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3081)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2888)
at com.sun.jndi.ldap.LdapCtx.c_listBindings(LdapCtx.java:1189)
at com.sun.jndi.toolkit.ctx.ComponentContext.p_listBindings(ComponentContext.java:592)
at com.sun.jndi.toolkit.ctx.PartialCompositeContext.listBindings(PartialCompositeContext.java:330)
at com.sun.jndi.toolkit.ctx.PartialCompositeContext.listBindings(PartialCompositeContext.java:317)
at javax.naming.InitialContext.listBindings(InitialContext.java:472)
at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:136)
at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:145)
at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:110)
at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.lifecycleEvent(GlobalResourcesLifecycleListener.java:82)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:94)
at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:401)
at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:345)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:784)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152)
at org.apache.catalina.startup.Catalina.start(Catalina.java:655)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:355)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:495)
Preguntas e investigaciones Similar sugieren un DN de LDAP no válido, pero:
- La misma configuración LDAP funciona bien a través de un cliente LDAP
- No se realiza ninguna búsqueda, en el momento de la puesta en marcha, Tomcat lanza esta excepción sin ninguna consulta.
- El error sugiere una cadena vacía
''''
comoremaining name
, por lo tanto, no es realmente algo que no se encuentra, aparentemente
Pregunta (s) : ¿Es esta la forma correcta de migrar una entrada de proveedores JNDI extranjeros de WebLogic a Tomcat? ¿Cómo arreglar una entrada de DN LDAP no válida con un nombre restante vacío? ¿Podría ser una baseDN
faltante para configurar en algún lugar?
Actualizar
El mismo error exacto ocurre cuando se cambia LdapContextFactory
a lo siguiente, como se sugiere a través de los comentarios:
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment)
throws Exception {
Hashtable<Object, Object> env = new Hashtable<>();
Reference reference = (Reference) obj;
Enumeration<RefAddr> references = reference.getAll();
String providerUrl = "no valid URL";
while (references.hasMoreElements()) {
RefAddr address = references.nextElement();
String type = address.getType();
String content = (String) address.getContent();
switch (type) {
case Context.PROVIDER_URL:
env.put(Context.PROVIDER_URL, content);
providerUrl = content;
break;
default:
env.put(type, content);
break;
}
}
InitialLdapContext context = null;
Object result = null;
try {
context = new InitialLdapContext(env, null);
LOGGER.info("looking up for " + providerUrl);
result = context.lookup(providerUrl);
} finally {
if (context != null) {
context.close();
}
}
LOGGER.info("Created new LDAP Context");
return result;
}
El cambio se confirma a través del registro, para asegurarse de que se implementó correctamente.
La escucha involucrada se define de manera predeterminada en la parte superior del archivo server.xml
como
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
Y no puede ser deshabilitado según la documentación oficial :
La escucha del ciclo de vida de los recursos globales inicializa los recursos JNDI globales definidos en
server.xml
como parte del elemento de recursos globales. Sin este oyente, ninguno de los recursos globales estará disponible.
Lo mismo ocurre con la versión 8.5.5 y 7.0.69 de Tomcat : simplemente agregando el nuevo recurso global como se indica arriba y el archivo adicional que proporciona la fábrica anterior, se lanzará la excepción que apunta a un nombre vacío.