0

I'm using spring-security to authenticate simply , and apacheDS via a simple ldif file:

<!-- BEGIN LDIF CONFIGURATION -->

<security:ldap-server ldif="classpath:spring-security-on-LDIF.ldif" root="dc=foo,dc=com" />

<bean id="userDetailsContextMapper" class="com.foo.myapp.login.springsecurity.MyLdapUserDetailsMapper">
    <constructor-arg ref="MyUserDetailsService" /> 
</bean>

<security:authentication-manager alias="authenticationManager" >
    <security:ldap-authentication-provider user-search-base="ou=users" user-search-filter="uid={0}" user-context-mapper-ref="userDetailsContextMapper"/>
</security:authentication-manager>
<!--  END LDIF CONFIGURATION -->

That works fine. Now I want to add a NEW user to my .ldif file. Unfortunately, I need to restart tomcat to get it to reread the .ldif file. Is there a way to force apacheDS to reread/recache the ldif file at a certain point?

Geoff G
  • 11
  • 6
  • Could be because you are using Embedded LDAP instead of the real one. Try again with a proper LDAP. – Jay Mar 07 '14 at 16:41
  • I know, I know...I have another version of the app that uses a real ldap -- but some of our customers/sales folks/testers found restarting tomcat when they run in THIS mode to be a pain. I was hoping there was a solution – Geoff G Mar 07 '14 at 16:46
  • I don't understand your setup. Is is some web application which you have deployed on Tomcat ? And you authenticate the users of this web app through the data in ApacheDS. If that's the case once you added the new user and then when to try to authenticate the 2nd user at that time it would try to bind on the LDAP with this new user. And it should work fine. Only if you have it in a ldif file classpath and if you change the ldif then a tomcat restart might be needed. – Jay Mar 07 '14 at 17:05
  • yes, its a web application which i have deployed on tomcat. yes, we authenticate through apacheDS, yes, the ldif file is in the classpath. I was thinking there might be a way to get it to re-load the ldif file that is in the classpath (it changed on disk when you edited it), or is there perhaps a better way to store the ldif file than in the classpath? – Geoff G Mar 07 '14 at 18:59
  • This problem is because you have it as a file instead of in real LDAP. Do you have it in a ldif file in your production environment as well ? – Jay Mar 08 '14 at 07:37
  • Nope, production envt talks to an active directory server which works perfectly – Geoff G Mar 08 '14 at 22:30

1 Answers1

0

Well, I think I figured it out. You get the ApacheDSContainer from the context, and call its destroy() (which calls stop and destroys the workingDir). Then you call afterPropertiesSet() (which creates the workingDir and then also calls start()). It appears to work quite well. I do this whenever I see the file changes. I used an org.apache.commons.io.monitor.FileAlterationListener to watch the .ldif file, which fires the onFileChange() at the appropriate time.

import org.springframework.security.config.BeanIds;
import org.springframework.security.ldap.server.ApacheDSContainer;
...
public void onFileChange(File file) {
    ApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext();  
    if (ctx == null)
        return; 
    ApacheDSContainer container = (ApacheDSContainer)ctx.getBean(BeanIds.EMBEDDED_APACHE_DS); 

    if (container != null) {
        try {
            container.destroy();
            container.afterPropertiesSet();
        }
        catch(Exception exec) {
            // handle error
        }
    }
}
Geoff G
  • 11
  • 6