Externalizing Spring Security configuration?
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 w开发者_运维百科ould 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?
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>
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>
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>
Spring comes with a couple of options for externalizing Spring configuration details into property files that can be managed outside of the deployed application:
- Property placeholder configurers replace placeholder variables placed in property values with values from an external properties file.
- 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
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.
精彩评论