Spring Boot Actuator - LDAP Health Endpoint Throwing NPE
Solution 1
This is a spring-ldap bug that has a fix committed, but it doesn't appear to be merged into the main spring-ldap
branch yet.
However, I have found that adding this property in application.properties
fixes the issue:
management.health.ldap.enabled=false
Solution 2
Another solution is to enter credentials into the LDAP Spring properties so they are picked up by the LDAPAutoConfiguration:
[email protected]
spring.ldap.password=secret
spring.ldap.urls=ldap://mydomain.com:389
This way, you can still use the health check.
Related videos on Youtube
justbaum30
Updated on June 04, 2022Comments
-
justbaum30 almost 2 years
In our Spring Boot app we have are using
spring-security-ldap
to authenticate users that can access our app. We don't see any issues functionally with authentication, however when we hit the/authenticator/health
URL, we get the following status for the ldap:"ldap": { "status": "DOWN", "error": "java.lang.NullPointerException: null" }
Tracking down this null pointer exception, we get this trace when trying to access the
env.put(Context.SECURITY_PRINCIPAL, userDn);
:java.lang.NullPointerException: null at java.util.Hashtable.put(Unknown Source) ~[na:1.8.0_111] at org.springframework.ldap.core.support.SimpleDirContextAuthenticationStrategy.setupEnvironment(SimpleDirContextAuthenticationStrategy.java:42) ~[spring-ldap-core-2.3.1.RELEASE.jar:2.3.1.RELEASE] at org.springframework.ldap.core.support.AbstractContextSource.setupAuthenticatedEnvironment(AbstractContextSource.java:194) ~[spring-ldap-core-2.3.1.RELEASE.jar:2.3.1.RELEASE] at org.springframework.ldap.core.support.AbstractContextSource.getAuthenticatedEnv(AbstractContextSource.java:582) ~[spring-ldap-core-2.3.1.RELEASE.jar:2.3.1.RELEASE] at org.springframework.ldap.core.support.AbstractContextSource.doGetContext(AbstractContextSource.java:134) ~[spring-ldap-core-2.3.1.RELEASE.jar:2.3.1.RELEASE] at org.springframework.ldap.core.support.AbstractContextSource.getReadOnlyContext(AbstractContextSource.java:158) ~[spring-ldap-core-2.3.1.RELEASE.jar:2.3.1.RELEASE] at org.springframework.ldap.core.LdapTemplate.executeReadOnly(LdapTemplate.java:802) ~[spring-ldap-core-2.3.1.RELEASE.jar:2.3.1.RELEASE] at org.springframework.boot.actuate.health.LdapHealthIndicator.doHealthCheck(LdapHealthIndicator.java:46) ~[spring-boot-actuator-1.5.4.RELEASE.jar:1.5.4.RELEASE] at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:43) ~[spring-boot-actuator-1.5.4.RELEASE.jar:1.5.4.RELEASE] at org.springframework.boot.actuate.health.CompositeHealthIndicator.health(CompositeHealthIndicator.java:68) [spring-boot-actuator-1.5.4.RELEASE.jar:1.5.4.RELEASE] at org.springframework.boot.actuate.endpoint.HealthEndpoint.invoke(HealthEndpoint.java:81) [spring-boot-actuator-1.5.4.RELEASE.jar:1.5.4.RELEASE] at org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.getHealth(HealthMvcEndpoint.java:171) [spring-boot-actuator-1.5.4.RELEASE.jar:1.5.4.RELEASE] at org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(HealthMvcEndpoint.java:145) [spring-boot-actuator-1.5.4.RELEASE.jar:1.5.4.RELEASE] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_111] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_111] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_111] at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_111] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.15.jar:8.5.15] ...
Finally, here is what our security configuration looks like:
@Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Value("${security.ldap.url}") private String ldapUrl; @Value("${security.ldap.user-search-base}") private String ldapUserSearchBase; @Value("${security.ldap.group-search-base}") private String ldapGroupSearchBase; @Value("${security.ldap.group-role-attribute}") private String ldapGroupRoleAttribute; @Value("${security.ldap.authorized-role}") private String ldapAuthorizedRole; @Override protected void configure(HttpSecurity http) throws Exception { // secure all core/data rest endpoints with basic auth http.authorizeRequests() .antMatchers("/core/data/unauthenticated/**").permitAll() .antMatchers("/core/data/**").hasRole(ldapAuthorizedRole) .and().httpBasic() .and().csrf().disable(); // do not create sessions for security http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); } @Autowired public void configure(AuthenticationManagerBuilder auth) throws Exception { // use ldap as the authentication provider auth.ldapAuthentication() .userSearchBase(ldapUserSearchBase) .userSearchFilter("(uid={0})") .groupSearchBase(ldapGroupSearchBase) .groupSearchFilter("uniqueMember={0}") .groupRoleAttribute(ldapGroupRoleAttribute) .contextSource() .url(ldapUrl); } }
Now we do get a message in the console saying
2017-10-24 12:37:28.867 INFO 12788 --- [ restartedMain] o.s.l.c.support.AbstractContextSource : Property 'userDn' not set - anonymous context will be used for read-write operations
, but this is our expectation and we're good with that. It seems the health endpoints isn't respecting this. I can't tell if this is a bug with our code or if it's an issue with the autoconfiguration for Spring Boot.I'm a bit unfamiliar with how exactly the Actuator endpoints work, so apologize if this is somewhat obvious. Thanks!
-
belgoros almost 5 yearsI'm using
2.3.2-release
version ofspring-ldap-core
and addingmanagement.health.ldap.enabled=false
toapplication.yml
did fixed the problem :). -
pixel about 2 yearsIt does not fix the issue, it just removes LDAP check when hitting health endpoint
-
pixel about 2 yearsThis should be marked as an answer. This resolves the issue and /health actuator endpoint will report status of Ldap. The above accepted answer is incorrect as it does not solve connectivity issue with Ldap but just removes check for Ldap in the /health endpoint
-
pixel about 2 yearsThis does not fix the issue. It just removes LDAP check when hitting /actuator/health endpoint resulting in Ldap not being checked at all.