简体   繁体   中英

Switch LDAP connection at runtime in Spring

I am new to spring. Admins of my spring based web app want to configure settings from the web interface, so users can authenticate against LDAP server with their company username and password.

Change in LDAP settings should be possible without restarting the application. This might happen during a 'migration' or whatever reason. I have a couple beans, which need to be refreshed after the admin saves new settings for the LDAP server:

<bean id="ldapServer" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
    <constructor-arg>
        <list>
            <value>${ldap.url1}</value>
            ...
        </list>
    </constructor-arg>
    <constructor-arg value="${ldap.basedn}"</constructor-arg>
    <property name="referral" value="${ldap.referral}" />
    <property name="baseEnvironmentProperties">...</property>
    <property name="userDn" value="${ldap.username}" />
    <property name="password" value="${ldap.password}" />
</bean>

I am using Springframework 3.1.2. The problem is, there are constructor arguments, which I want to change and not affect other running jobs. I tried playing with Scoped proxy, but not to much success yet:

<bean id="ldapServer" scope="prototype" ...>
    <aop:scoped-proxy/>

I was successful though to get ldapServer to reinstantiate, when using prototype scope by running this piece of code:

@Controller
public class LDAPSettingsController implements ApplicationContextAware {
    public ModelAndView handleRequest(...) {
        DefaultSpringSecurityContextSource ldap;
        ldap = context.getParentBeanFactor().getBean("ldapServer");

        System.out.println(ldap.hashCode());

        return new ModelAndView(new RedirectView('login.jsp'));
    }
    ...
}

Are scopes and proxies here the way to go, or is the another mechanism in Spring to reflect configuration changes into a running program instance?

UPDATE: Clear up the question. UPDATE: The root problem with the AOP proxies was following root exception:

java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given

What worked was adding proxy-target-class="false" attribute to the <aop:scoped-proxy/> tag. I created a new scope, which works better than prototype - It destroys beans on settings update. Now I have this in my beans.xml:

<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
  <property name="scopes">
    <map>
      <entry key="ldap">
        <ref bean="ldapScope" />
      </entry>
    </map>
  </property>
</bean>

<bean id="ldapScope" class="com.myapp.SettingsScope" />

<bean id="ldapServer" scope="ldap" ...>
    <aop:scoped-proxy proxy-target-class="false"/>
    <constructor-args>
      <list><value>${ldap.url1}</value> .. </list>
    </constructor-args>
    ...
</bean>

I also have a controller for LDAP settings into which I inject ldapScope and I call a method which destroys current life-cycle objects and starts a new life-cycle every time, user presses the apply button.

PS: Not sure if I handle the life-cycle "re-start" in the right way - people my way to look for auto-start beans and start them after such event happens (ie: Setting -> Apply)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM