Ir al contenido

LDAP troubleshooting

Cómo hacer un filtro de pertenencia a grupos anidados en Active Directory

Sección titulada «Cómo hacer un filtro de pertenencia a grupos anidados en Active Directory»

El siguiente ejemplo muestra cómo configurar la búsqueda de AD para recuperar usuarios que son miembros de algún rol que a su vez es miembro de ROLE_OPENKM.

Campo / Propiedad Tipo Descripción
principal.ldap.user.search.filter String ((objectclass=user)((memberOf:1.2.840.113556.1.4.1941:=CN=ROLE_OPENKM,OU=OpenKM,DC=company,DC=com))

Error “No UserDetailsService registered”

Sección titulada «Error “No UserDetailsService registered”»

Si ve una excepción como esta “org.springframework.context.ApplicationContextException: No UserDetailsService registered,” puede añadir esta línea a su openkm.xml:

<beans:bean id="userDetailService" class="com.openkm.spring.UserTenantDetailsService"/>

Si ve una excepción como esta “javax.naming.PartialResultException” probablemente no pueda usar Active Directory basic configuration.

Solución 1:

Use los puertos 3268 o 3269 (LDAPS) para la conexión con AD.

Vaya a Administration > Configuration parameters:

Campo / Propiedad Tipo Descripción
principal.ldap.server String ldap://192.168.xxx.xxx:3268

Solución 2:

Habilite la propiedad de LDAP para ignorar la excepción de resultado parcial.

Vaya a Administration > Configuration parameters:

Campo / Propiedad Tipo Descripción
ldap.ignore.partial.result.exception Boolean true

Solución 3:

Habilite la propiedad de referral de LDAP.

Vaya a Administration > Configuration parameters:

Campo / Propiedad Tipo Descripción
principal.ldap.referral String follow

Lea estos artículos:

Si su servidor LDAP está configurado bajo SSL, entonces debe usar ldaps://.

Solución:

Vaya a Administration > Configuration parameters:

Cambie la URL de conexión del servidor a ldaps://.

Campo / Propiedad Tipo Descripción
principal.ldap.server String ldaps://192.168.0.6:389

Puede deberse a un problema con la resolución de nombres DNS de LDAP.

Solución:

Para evitar este problema —especialmente en la familia de sistemas operativos Windows— es buena práctica añadir todos los subdominios al fichero hosts del servidor de aplicaciones (/etc/hosts en Linux o C:\Windows\System32\drivers\etc\hosts en Windows).

Ejemplo basado en Active Directory (LDAP) con nombre base distinguido dc=company,dc=com y nombre de dominio del servidor SBSSERVER.

10.10.1.2 company.com
10.10.1.2 SBSSERVER SBSSERVER.company.com
10.10.1.2 Schema.Configuration.company.com
10.10.1.2 Configuration.company.com
10.10.1.2 DomainDnsZones.company.com
10.10.1.2 ForestDnsZones.company.com

Hay más información disponible en el foro de OpenKM.

Forzar que todos los usuarios sean miembros de ROLE_USER.

Sección titulada «Forzar que todos los usuarios sean miembros de ROLE_USER.»

En repositorios de usuarios de AD grandes, no es viable que el administrador de AD añada un nuevo grupo a todos los usuarios; en este caso, podemos forzar mediante la configuración XML de login que cualquier usuario que inicie sesión sea miembro de ROLE_USER. Añada la etiqueta XML <beans:property name=“defaultRole” value=“ROLE_USER” />.

Por ejemplo:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd">
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="ldapAuthProvider" />
</security:authentication-manager>
<beans:bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<beans:constructor-arg value="ldap://192.168.xxx.xxx"/>
<beans:property name="userDn" value="CN=connect,OU=OpenKM,DC=company,DC=com"/>
<beans:property name="password" value="****"/>
<beans:property name="baseEnvironmentProperties">
<beans:map>
<beans:entry>
<beans:key>
<beans:value>java.naming.referral</beans:value>
</beans:key>
<beans:value>follow</beans:value>
</beans:entry>
</beans:map>
</beans:property>
</beans:bean>
<beans:bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<beans:constructor-arg>
<beans:bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<beans:constructor-arg ref="contextSource"/>
<beans:property name="userSearch" ref="userSearch"/>
</beans:bean>
</beans:constructor-arg>
<beans:constructor-arg name="authoritiesPopulator" ref="defaultLdapAuthoritiesPopulator"/>
</beans:bean>
<beans:bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<beans:constructor-arg index="0" value="DC=company,DC=com" />
<beans:constructor-arg index="1" value="(&amp;(sAMAccountName={0})(|(memberOf=CN=ROLE_ADMIN,OU=OpenKM,DC=company,DC=com)(memberOf=CN=ROLE_USER,OU=OpenKM,DC=company,DC=com)))" />
<beans:constructor-arg index="2" ref="contextSource" />
<beans:property name="searchSubtree" value="true" />
</beans:bean>
<beans:bean id="defaultLdapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<beans:constructor-arg ref="contextSource"/>
<beans:constructor-arg value="DC=company,DC=com"/>
<beans:property name="groupSearchFilter" value="member={0}"/>
<beans:property name="groupRoleAttribute" value="cn"/>
<beans:property name="searchSubtree" value="true" />
<beans:property name="convertToUpperCase" value="false" />
<beans:property name="rolePrefix" value="" />
<beans:property name="defaultRole" value="ROLE_USER" />
</beans:bean>
<!--Needed for remember-me services -->
<beans:bean id="userDetailService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
<beans:constructor-arg ref="userSearch"/>
<beans:constructor-arg ref="defaultLdapAuthoritiesPopulator"/>
</beans:bean>
</beans:beans>

org.springframework.beans.factory.parsing.BeanDefinitionParsingException

Sección titulada «org.springframework.beans.factory.parsing.BeanDefinitionParsingException»

Si ve un error como este “org.springframework.beans.factory.parsing.BeanDefinitionParsingException” probablemente tenga configurada una versión incorrecta de Spring en el openkm.xml:

Solución:

Edite el fichero openkm.xml y elimine los números de versión:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd">

por

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd">

LDAP: error code 8 - BindSimple: Transport encryption required

Sección titulada «LDAP: error code 8 - BindSimple: Transport encryption required»

El error “transport encryption required” suele producirse al intentar conectar con LDAPS (cifrado SSL) sin haber configurado el certificado de confianza en el truststore de Java.

Primero, compruebe que está usando “ldaps://(termina en ‘s’) en su fichero openkm.xml para la conexión; cuando obtenga este error, úselo.

El primer paso es obtener el certificado del servidor; para ello, siga los pasos siguientes:

Ventana de terminal
$ openssl s_client -showcerts -connect your.ldap.server.com:636

La salida contendrá varias entradas delimitadas de la siguiente forma:

-----BEGIN CERTIFICATE-----
aklfhskfadljasdl1340234234ASDSDFSDFSDFSDFSD
....
-----END CERTIFICATE-----

Copie la última entrada del certificado en un fichero (ldapca.crt).
Después, añádalo al keystore de Java en $JRE_HOME/lib/security.

Ventana de terminal
$ cd $TOMCAT_HOME
$ mkdir jks
$ keytool -import -alias ldapca_self_sign -keystore cacerts -storepass changeit -file ldapca.crt

Finalmente, habilite el truststore en el fichero $TOMCAT_HOME/bin/setenv.sh

# JAVA enable trust store
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=/home/openkm/tomcat/jks/cacerts -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStoreType=JKS"

Error de LDAP: Caused by java.security.cert.CertificateException: No subject alternative DNS name matching

Sección titulada «Error de LDAP: Caused by java.security.cert.CertificateException: No subject alternative DNS name matching»

En el log puede ver trazas de error como estas:

Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching ldap.openkm.com found.
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:214)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:96)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:459)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:200)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)
... 72 more

O como esta:

Caused by: org.springframework.ldap.CommunicationException: simple bind failed: ldap.openkm.com:636; nested exception is javax.naming.CommunicationException: simple bind failed: email.ied.edu.hk:636 [Root exception is javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching email.ied.edu.hk found.]
at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:100)
at org.springframework.ldap.core.support.AbstractContextSource.createContext(AbstractContextSource.java:285)
at org.springframework.ldap.core.support.AbstractContextSource.doGetContext(AbstractContextSource.java:119)
at org.springframework.ldap.core.support.AbstractContextSource.getReadOnlyContext(AbstractContextSource.java:138)
at org.springframework.ldap.core.LdapTemplate.executeReadOnly(LdapTemplate.java:791)
at org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleEntry(SpringSecurityLdapTemplate.java:194)
at org.springframework.security.ldap.search.FilterBasedLdapUserSearch.searchForUser(FilterBasedLdapUserSearch.java:116)
at org.springframework.security.ldap.authentication.BindAuthenticator.authenticate(BindAuthenticator.java:90)
at org.springframework.security.ldap.authentication.LdapAuthenticationProvider.doAuthentication(LdapAuthenticationProvider.java:178)

Modifique los parámetros de configuración de la JVM en setenv.sh o setenv.bat añadiendo el parámetro de configuración de la JVM:

Ventana de terminal
-Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true