Spring Boot Actuator - LDAP Health Endpoint Throwing NPE

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!

2 Answers

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 
3

Another solution is to enter credentials into the LDAP Spring properties so they are picked up by the LDAPAutoConfiguration:

spring.ldap.username= spring.ldap.password=secret spring.ldap.urls=ldap://mydomain.com:389 

This way, you can still use the health check.

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like