Announcement Announcement Module
No announcement yet.
Subverting DI so a password can be entered by the user Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Subverting DI so a password can be entered by the user

    I have set up a 'secure' HttpInvoker invoked service call that works fine. It is as per pages 586-588 of the Pro Spring book. My problem with it is that the password is in a config file (actually it will be a resource in a jar but that's not a secure place for it to be either). I want the user to enter the password. I'm new to Spring and have been battling with this problem here ( Basically the point that I've reached is needing to code the bean definition file directly - that way the password can be set at runtime. Is there any other way? This is where I am trying to replicate the bean as code:

        public void invoke()
            HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
            properties = PropertyUtils.getProperties( PROPS);
            String serverName = PropertyUtils.getProperty( "serverName", properties);
            String httpPort = PropertyUtils.getProperty( "httpPort", properties);
            String contextPath = PropertyUtils.getProperty( "contextPath", properties);
            proxy.setServiceUrl( "http://" + serverName + ":" + httpPort + contextPath + "/httpinvoker/rosterServiceSecure");
            proxy.setServiceInterface( example.spring.RosterService.class);
            HttpInvokerRequestExecutor httpInvokerRequestExecutor = obtainHttpInvokerRequestExecutor();
            proxy.setHttpInvokerRequestExecutor( httpInvokerRequestExecutor);
            //What to do now? When everything was in the bean I could just:
            //RosterService rosterService = (RosterService)beanFactory.getBean( "rosterServiceSecure");
            //String roster = rosterService.getRoster( MonthInYear.JULY, 2006);
            //But there is no beanFactory, just an object graph of what is in a bean
        private HttpInvokerRequestExecutor obtainHttpInvokerRequestExecutor()
            CommonsHttpInvokerRequestExecutor result = new CommonsHttpInvokerRequestExecutor();
            result.setHttpClient( obtainHttpClient());
            return result;
        private HttpClient obtainHttpClient()
            HttpClient result = null;
            HttpClientFactoryBean resultBean = new HttpClientFactoryBean();
            resultBean.setUsername( PropertyUtils.getProperty( "userName", properties));
            resultBean.setPassword( PropertyUtils.getProperty( "password", properties));
                result = (HttpClient)resultBean.getObject();
            catch(Exception e)
                Err.error( e);
            return result;
    I find myself wishing that as well as there being a PropertiesBeanDefinitionReader and an XmlBeanDefinitionReader, there was also an ObjectGraphDefinitionReader. I would like to be able to construct the beanFactory like this:

            ListableBeanFactory beanFactory = new ObjectGraphApplicationContext( proxy);
    I imagine that this all seems like a bit of a descent into madness from a Spring user's point of view, which is why I'm here. Am I right in thinking that there is no way to dynamically 'get at' the bean before it starts to realise itself? Another way of putting this: "Am I right in thinking that Spring is only to be used for design-time configuration"? How should I really be going about solving this problem?

    Any help appreciated - Chris Murphy

  • #2
    One approach for combining Spring's configuration with the possibility for providing runtime parameters I proposed here. Maybe it might be useful for you.



    • #3
      Thanks Andreas,
      I didn't use your suggestion as I wanted to get back on the straight and narrow, and thought that Acegi might be able to help here, and it did. After lots of reading around I deployed acegi-security-sample-contacts-filter.war (see and got the non-web client going. For this client I grabbed the latest nightly SVN snapshot from (which you get to from The secret is all in the AuthenticationSimpleHttpInvokerRequestExecutor. I didn't need to make any alterations on the server side, and the client code and bean file are quite small, so here they are:
      package example.spring;
      import org.acegisecurity.Authentication;
      import org.acegisecurity.context.SecurityContextHolder;
      import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
      import org.springframework.beans.factory.ListableBeanFactory;
      import org.strandz.lgpl.util.Err;
      public class ScratchRosterClient
          private static final String CLIENT_CONTEXT_CONFIG_LOCATION = "clientContext.xml";
          private final ListableBeanFactory beanFactory;
          public ScratchRosterClient(ListableBeanFactory beanFactory)
              this.beanFactory = beanFactory;
          public void invoke(Authentication authentication)
              RosterService rosterService = (RosterService)beanFactory.getBean( "rosterServiceSecure");
              String roster = rosterService.getRoster( MonthInYear.JULY, 2006);
     "Roster: " + roster);
          public static void main(String[] args)
              ListableBeanFactory beanFactory = new FileSystemXmlApplicationContext(ScratchRosterClient.CLIENT_CONTEXT_CONFIG_LOCATION);
              ScratchRosterClient client = new ScratchRosterClient(beanFactory);
              String username = "tomcat";
              String password = "tomcat";
              client.invoke(new UsernamePasswordAuthenticationToken(username, password));
        <!-- Resolves ${...} placeholders from -->
        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
          <property name="location"><value></value></property>
        <bean id="rosterServiceSecure" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
          <property name="serviceUrl">
          <property name="serviceInterface">
          <property name="httpInvokerRequestExecutor">
            <ref local="httpInvokerRequestExecutor"/>
        <!-- Automatically propagates ContextHolder-managed Authentication principal
             and credentials to a HTTP invoker BASIC authentication header -->
        <bean id="httpInvokerRequestExecutor" class="org.acegisecurity.context.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor"/>
      A full tutorial for rich client users is available here
      Last edited by cjmurphy; Jan 4th, 2007, 06:48 PM.