Externalizing Spring Security configuration?

2019-07-10 08:52发布

问题:

I have a web application that works with several different configurations of Spring Security already. However, these difference configuration are all setup within my applicationContext configuration file. Therefore, in order to tweak these at a customer site, these would have to be modified INSIDE the WAR file. If customers manually modify the WAR file, then they'll lose their changes after redeploying a new WAR.

Is there a way to externalize this configuration? Is there a way I can load the configuration using JNDI somehow?

回答1:

It's an interesting question. Since Spring Security should be configured in root webapp context, you can't externalize its configuration to other contexts. Also you can't change the set of config resources from inside the context. So, you should do it from outside:

  • You can use a well-known file system location:

     <context-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>
             /WEB-INF/applicationContext.xml
             file:///C:\config.xml
         </param-value>
     </context-param>
    
  • System properties are resolved in contextConfigLocation, so you can use it:

     <context-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>
             /WEB-INF/applicationContext.xml
             file:///${configPath}
         </param-value>
     </context-param>
    

    and -DconfigPath=...

  • You can override XmlWebApplicationContext.getResource() and implement whatever you want:

    public class MyXmlWebApplicationContext extends XmlWebApplicationContext {
        private static final String JNDI_PREFIX = "jndi:/";        
        @Override
        public Resource getResource(String location) {
            if (location.startsWith(JNDI_PREFIX)) return getJndiResource(location);
            else return super.getResource(location);
        }
        protected Resource getJndiResource(String location) { ... }
    }
    

    and

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext.xml
            jndi:/...
        </param-value>
    </context-param>        
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>com.example.MyXmlWebApplicationContext</param-value>
    </context-param>
    


回答2:

Alternatively you can use org.springmodules.commons.configuration.CommonsConfigurationFactoryBean to store and retrieve your configuration as key, value pair in database table

    <bean name="DatabaseConfiguration" class="org.apache.commons.configuration.DatabaseConfiguration">
            <constructor-arg type="javax.sql.DataSource" ref="dataSource"/>
            <constructor-arg index="1" value="CONFIG_TABLE_NAME"/>
            <constructor-arg index="2" value="KEY_COLUMN_NAME"/>
            <constructor-arg index="3" value="VALUE_COLUMN_NAME"/>
    </bean>


回答3:

You can add a org.springframework.beans.factory.config.PropertyPlaceholderConfigurer, which references an external file, then use the ${key} syntax without your Spring configuration files to reference key/value pairs in the externalized property file.

Another solution is to specify an absolute path in your web.xml to reference a Spring contextConfigLocation.

<context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>/absolute_path/ldap.xml, /WEB-INF/context/dao-context.xml</param-value>
</context-param> 


回答4:

Here is a free configuration tool: http://go.eeye.com/icwt that tests your environment for highly recommended configuration updates, how the local OS is configured (identifies potential problem areas), identifies areas concerning APTs, and shows if your processes and code are signed.



回答5:

Spring comes with a couple of options for externalizing Spring configuration details into property files that can be managed outside of the deployed application:

  1. Property placeholder configurers replace placeholder variables placed in property values with values from an external properties file.
  2. Property overriders override bean property values with values from an external properties file. In addition, the open source Jasypt project offers alternative implementations ofS pring’s property placeholder configurer and overrider that can pull those values from encrypted properties files. A placeholder configurer can be configured like this for classpath A placeholder configurer can be configured like this for filepath if db.properties contains as follows jdbc.driverClassName=DriverclassName jdbc.url=Driverclass://localhost/applicationname/ jdbc.username=test jdbc.password=test1 Now we can replace the hardcoded values in the Spring configuration with place-holder variables based on the properties in db.properties


回答6:

It depends. If you want modify authorizations, you can use Requestmap and save all the authorization configurations in database, then deliver different versions with external bootstrap data definitions.