LDAP troubleshooting

javax.naming.PartialResultException error

If you see an exception like this "javax.naming.PartialResultException" probably you can not use Active Directory basic configuration.

javax.naming.PartialResultException: Unprocessed Continuation Reference(s); remaining name 'cn=users,dc=company,dc=com'

Solution 1:

Use the port 3268 or 3269 in the connection of the AD.

Go to Administration > Configuration parameters:

Field / PropertyTypeDescription
principal.ldap.server String

ldap://192.168.xxx.xxx:3268

Solution 2:

Enable ldap referral property.

Go to Administration > Configuration parameters:

Field / PropertyTypeDescription
principal.ldap.referral String

follow

Read these articles:

Can't connect to LDAP server

If your LDAP server is configured under SSL then you should use ldaps://

Solution:

Go to Administration > Configuration parameters:

Change server connection URL to ldaps.

Field / PropertyTypeDescription
principal.ldap.server String

ldaps://192.168.0.6:389

Slow login or not able to login

It may be a problem with LDAP DNS names resolution.

Solution:

To prevent this issue - specially on Windows OS Family - it's a good practice to add all subdomains in application server's hosts file ( /etc/hosts for linux or C:/Windows/system32/driver/etc/host for windows ).

Example based with active directory ( LDAP ) with distinguished base name dc=company,dc=com and server at SBSSERVER domain server name.

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

More information at OpenKM forum.

If after added these subdomains the login it continues talking a lot of time, check with your IT Security team if have enabled some policies for micro-segmentation. That may be another reason why login takes so much time.

Force all users to be members of ROLE_USER

In a huge user AD repositories, can not be practice for the AD administrator to adding a new group to all the users, in this case we can force across xml login configuration that any logged user be member of ROLE_USER. Must be added the xml tag <beans:property name="defaultRole" value="ROLE_USER" />.

For example:

<?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>
    <beans:bean 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>
  </beans:constructor-arg>
</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:beans>

org.springframework.beans.factory.parsing.BeanDefinitionParsingException

If you see an error like this "org.springframework.beans.factory.parsing.BeanDefinitionParsingException" probably you have some spring wrong version set in the OpenKM.xml:

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: You cannot use a spring-security-2.0.xsd or spring-security-3.0.xsd or spring-security-3.1.xsd schema with Spring Security 3.2. Please update your schema declarations to the 3.2 schema.
Offending resource: URL [file:/desarrollo/tomcat/tomcat-7.0.61-openkm-6.4/OpenKM.xml]
    at org.springframework.beans.factory.parsing.FailFastProblemReporter.fatal(FailFastProblemReporter.java:59)

Solution:

Edit the OpenKM.xml file and remove the version numbers:

<?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">

to

<?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

The transport encryption required error usually happens when you are trying to connect with ldaps ( with SSL encryption ) and you have not configured the trust certificate into the JAVA certs storage.

First, check you are using "ldaps://" - ends with s - in your OpenKM.xml file for the connection, when you get this error you sould use it.

The first step is to get the certificate from the server for it follow the steps below:

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

The OpenSSL windows binaries https://wiki.openssl.org/index.php/Binaries ( version tested https://indy.fulgan.com/SSL/ )

The output will contain a number of entries delimited with:

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

To prevent loss of JKS after the Java upgrade does not create the JKS under the JDK folders.

In the sample below it is supposed the $TOMCAT_HOME is set to /home/openkm/tomcat

Copy the last certificate entry into a file (ldapca.crt)
Then, add it to the java keystore in $JRE_HOME/lib/security

$ cd $TOMCAT_HOME

$ mkdir jks
$ keytool -import -alias ldapca_self_sign -keystore cacerts -storepass changeit -file ldapca.crt

 

Finally enable trust store into the file $TOMCAT_HOME/bin/setenv.sh

# JAVA enable trust store
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=/etc/pki/java/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

In the log maybe show some stack trace error like:

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

Or like:

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)

Modify JVM configuration parameters in setenv.sh or setenv.bat adding the JVM configuration parameter:

-Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true