DHIS2 with openLDAP

Using docker,Im trying to configure DHIS2 to authenticate with openLDAP's users.

Following https://docs.dhis2.org/en/full/manage/dhis-core-version-234/system-administration-guide.html#install_ldap_configuration I maked this dhis2.conf:

# ----------------------------------------------------------------------
# Database connection
# ----------------------------------------------------------------------

# JDBC driver class
connection.driver_class = org.postgresql.Driver

# Database connection URL
connection.url = jdbc:postgresql://db/dhis2

# Database username
connection.username = dhis

# Database password
connection.password = dhis

# ----------------------------------------------------------------------
# Server
# ----------------------------------------------------------------------

# Enable secure settings if deployed on HTTPS, default 'off', can be 'on'
# server.https = on

# Server base URL
# server.base.url = https://server.com
# LDAP server URL
ldap.url = ldap://openldap:1389

# LDAP manager entry distinguished name
ldap.manager.dn = cn=user01,dc=example,dc=org

# LDAP manager entry password
ldap.manager.password = password1

# LDAP base search
ldap.search.base = dc=example,dc=org

# LDAP search filter
ldap.search.filter = (cn={0})

Moreover, my docker-compose is:

version: '3'
services:
  db:
    image: mdillon/postgis:10-alpine
    command: postgres -c max_locks_per_transaction=100
    environment:
      POSTGRES_USER: dhis
      POSTGRES_DB: dhis2
      POSTGRES_PASSWORD: dhis
  web:
    image: dhis2/core:2.33.0
    volumes:
    - ./config/dhis2_home/dhis.conf:/DHIS2_home/dhis.conf
    ports:
    - "8080:8080"
    depends_on:
    - db
  openldap:
    image: docker.io/bitnami/openldap:2.6
    ports:
      - '1389:1389'
      - '1636:1636'
    environment:
      - LDAP_ADMIN_USERNAME=dhis
      - LDAP_ADMIN_PASSWORD=dhis
      - LDAP_CONFIG_ADMIN_USERNAME=dhis
      - LDAP_CONFIG_ADMIN_PASSWORD=dhis
      - LDAP_USERS=ftacoronte,user01,user02
      - LDAP_PASSWORDS=prueba,password1,password2
      - LDAP_LOGLEVEL=-1
    volumes:
      - 'openldap_data:/bitnami/openldap'
volumes:
  openldap_data:
    driver: local

I can log with the default DHIS2's user:

Username: admin

Password: district

But then I add the user on DHIS2 front-end and It doesn´t work (I can´t use it to log-on). The log show the next error:

web_1       | * INFO  2022-05-04 11:04:16,646 Login attempt: ftacoronte (TwoFactorAuthenticationProvider.java [http-nio-8080-exec-4])
web_1       | * ERROR 2022-05-04 11:04:16,659 An internal error occurred while trying to authenticate the user. (AbstractAuthenticationProcessingFilter.java [http-nio-8080-exec-4])
web_1       | org.springframework.security.authentication.InternalAuthenticationServiceException: Cannot pass null or empty values to constructor
web_1       |   at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:123)
web_1       |   at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:144)
web_1       |   at org.hisp.dhis.security.spring2fa.TwoFactorAuthenticationProvider.authenticate(TwoFactorAuthenticationProvider.java:130)
web_1       |   at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175)
web_1       |   at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:200)
web_1       |   at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
web_1       |   at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
web_1       |   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
web_1       |   at org.hisp.dhis.security.filter.CustomAuthenticationFilter.doFilter(CustomAuthenticationFilter.java:69)
web_1       |   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
web_1       |   at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:176)
web_1       |   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
web_1       |   at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
web_1       |   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
web_1       |   at org.hisp.dhis.security.filter.AutomaticAccessFilter.doFilter(AutomaticAccessFilter.java:115)
web_1       |   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
web_1       |   at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
web_1       |   at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
web_1       |   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
web_1       |   at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
web_1       |   at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
web_1       |   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
web_1       |   at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
web_1       |   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
web_1       |   at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
web_1       |   at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
web_1       |   at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
web_1       |   at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
web_1       |   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
web_1       |   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
web_1       |   at org.hisp.dhis.servlet.filter.HttpUrlPatternFilter.doFilter(HttpUrlPatternFilter.java:120)
web_1       |   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
web_1       |   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
web_1       |   at org.springframework.orm.hibernate5.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:155)
web_1       |   at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
web_1       |   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
web_1       |   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
web_1       |   at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
web_1       |   at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
web_1       |   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
web_1       |   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
web_1       |   at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
web_1       |   at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
web_1       |   at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
web_1       |   at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
web_1       |   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
web_1       |   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
web_1       |   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
web_1       |   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
web_1       |   at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
web_1       |   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
web_1       |   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
web_1       |   at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
web_1       |   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
web_1       |   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
web_1       |   at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
web_1       |   at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
web_1       |   at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
web_1       |   at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
web_1       |   at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
web_1       |   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
web_1       |   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
web_1       |   at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
web_1       |   at java.lang.Thread.run(Thread.java:748)
web_1       | Caused by: java.lang.IllegalArgumentException: Cannot pass null or empty values to constructor
web_1       |   at org.springframework.security.core.userdetails.User.<init>(User.java:113)
web_1       |   at org.hisp.dhis.security.DefaultUserDetailsService.loadUserByUsername(DefaultUserDetailsService.java:112)
web_1       |   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
web_1       |   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
web_1       |   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
web_1       |   at java.lang.reflect.Method.invoke(Method.java:498)
web_1       |   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
web_1       |   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
web_1       |   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
web_1       |   at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295)
web_1       |   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
web_1       |   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
web_1       |   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
web_1       |   at com.sun.proxy.$Proxy219.loadUserByUsername(Unknown Source)
web_1       |   at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:108)
web_1       |   ... 63 more

Somebody can help me?

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum