Resolución de problemas de LDAP
Cómo realizar un filtro de pertenencia a grupos anidados en Active Directory
Sección titulada «Cómo realizar un filtro de pertenencia a grupos anidados en Active Directory»El siguiente ejemplo muestra cómo configurar la búsqueda en AD para obtener los usuarios que son miembros de un 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"/>Error javax.naming.PartialResultException
Sección titulada «Error javax.naming.PartialResultException»Si ve una excepción como esta “javax.naming.PartialResultException”, probablemente no pueda utilizar la configuración básica de Active Directory.
Solución 1:
Utilice 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:
No se puede conectar con el servidor LDAP
Sección titulada «No se puede conectar con el servidor LDAP»Si su servidor LDAP está configurado con SSL, debe utilizar 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 |
Inicio de sesión lento o imposibilidad de iniciar sesión
Sección titulada «Inicio de sesión lento o imposibilidad de iniciar sesión»Puede tratarse de un problema con la resolución de nombres DNS de LDAP.
Solución:
Para evitar este problema —especialmente en sistemas Windows— es buena práctica añadir todos los subdominios al archivo 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 servidor de dominio SBSSERVER.
10.10.1.2 company.com10.10.1.2 SBSSERVER SBSSERVER.company.com10.10.1.2 Schema.Configuration.company.com10.10.1.2 Configuration.company.com10.10.1.2 DomainDnsZones.company.com10.10.1.2 ForestDnsZones.company.comMás información 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 resulta práctico que el administrador de AD añada un nuevo grupo a todos los usuarios; en este caso, podemos forzar desde la configuración XML del inicio de sesión que cualquier usuario autenticado sea miembro de ROLE_USER. Debe añadir 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="(&(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 tiene establecida una versión de Spring incorrecta en openkm.xml:
Solución:
Edite el archivo 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 cuando intenta conectarse con LDAPS (con cifrado SSL) y no ha configurado el certificado de confianza en el almacén de claves (keystore) de Java.
Primero, compruebe que está utilizando “ldaps://” (termina en ‘s’) en su archivo openkm.xml para la conexión; cuando obtenga este error, utilícelo.
El primer paso es obtener el certificado del servidor; para ello siga los pasos siguientes:
$ openssl s_client -showcerts -connect your.ldap.server.com:636La salida contendrá varias entradas delimitadas con lo siguiente:
-----BEGIN CERTIFICATE-----aklfhskfadljasdl1340234234ASDSDFSDFSDFSDFSD....-----END CERTIFICATE-----Copie la última entrada de certificado en un archivo (ldapca.crt)
Después, añádalo al keystore de java en $JRE_HOME/lib/security
$ cd $TOMCAT_HOME$ mkdir jks$ keytool -import -alias ldapca_self_sign -keystore cacerts -storepass changeit -file ldapca.crtPor último, habilite el trust store en el archivo $TOMCAT_HOME/bin/setenv.sh
# JAVA enable trust storeJAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=/home/openkm/tomcat/jks/cacerts -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStoreType=JKS"Ldap error: Caused by java.security.cert.CertificateException: No subject alternative DNS name matching
Sección titulada «Ldap error: Caused by java.security.cert.CertificateException: No subject alternative DNS name matching»El registro puede mostrar una traza de pila como:
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 moreO como:
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:
-Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true