Encrypting content in the security.xml file

As of Weave 2.5.16 and 2.5.15.5 it's possible to encrypt the password, and in fact any values, that are stored in the security.xml file using the same encryption that is used to encrypt passwords in the other Weave configuration files.

The encrypted values generated with the encrypt command are dependant upon the private.key file, if you want to use the same encrypted text on multiple Weave instances you should ensure they all use the same private.key file as the instance used to generate the original encrypted text.

Directly encrypting passwords

If you just want to encrypt the passwords stored in the security.xml file you first need to encrypt the original value using the osgi encrypt command, e.g.

osgi> encrypt $up3r$3cr3tP@55w0rd
ENCEAUFJCUABCFXEMFQABFJEBZJAKFCXGME

Then you need to add a new bean to the security.xml file so that the encrypted values are decoded when processing the security.xml file, e.g. 

<bean class="com.cohga.beans.factory.config.EncryptedPasswordProcessor">
	<property name="key" value="private.key"/>
</bean>

The key value should almost always be set to private.key, which is the name of the key file that Weave uses to encrypt/decrypt the passwords. 

The above example shows how the bean would be defined in the older Acegi Security file, in the newer Spring Security file the bean and property tags would probably need to include a beans namespace prefix, e.g.

<beans:bean class="com.cohga...

	<beans:property name="key...
</beans:bean>

Once you've added the EncryptedPasswordProcessor bean you can then update the passwords in the security.xml file to use the encrypted value, e.g.

<bean id="initialDirContextFactory" class="org.acegisecurity.ldap.DefaultInitialDirContextFactory">
	<constructor-arg value="ldap://10.0.12.213:389/" />
	<property name="managerDn">
		<value>CN=Administrator,CN=Users,DC=adel,DC=cohga,DC=com</value>
	</property>
	<property name="managerPassword">
		<value>ENCEAUFJCUABCFXEMFQABFJEBZJAKFCXGME</value>
	</property>
</bean>

Here the managerPassword value has been changed to use the encrypted password.

Using an external properties file

To do this you need to first encrypt the passwords at the osgi console using the encrypt command, e.g.

osgi> encrypt $up3r$3cr3tP@55w0rd
ENCEAUFJCUABCFXEMFQABFJEBZJAKFCXGME

Then you create a properties file to store the value(s), named security.properties for example, and add a key/value line for each value you want to use, e.g.

password=ENCEAUFJCUABCFXEMFQABFJEBZJAKFCXGME

After you've setup the properties file with all the encrypted values you want to use in security.xml you need to update security.xml so that it firstly knows that it should get values from the new properties file and secondly replace the unencrypted values with references to the encrypted properties.

The first step, loading the properties, is done by adding a new reference to an EncryptedPropertyPlaceholderConfigurer, note that this is an extension of the standard PropertyPlaceholderConfigurer which  allows you to store properties to use in security.xml in an external file but the file contents aren't encrypted. This new bean can be added anywhere in the file and is not directly referenced by any other beans, you just need to add the definition. 

<bean class="com.cohga.beans.factory.config.EncryptedPropertyPlaceholderConfigurer">
	<property name="key" value="private.key"/>
	<property name="locations" value ="security.properties" />
</bean>

The key value should almost always be set to private.key, which is the name of the key file that Weave uses to encrypt/decrypt the passwords. The locations value should point to the name of the file that contains the properties that you've encrypted, the file can be called anything as long as this properties points to that file.

The above example shows how the bean would be defined in the older Acegi Security file, in the newer Spring Security file the bean and property tags would probably need to include a beans namespace prefix, e.g.

<beans:bean class="com.cohga...

	<beans:property name="key...
</beans:bean>

Once you've added the EncryptedPropertyPlaceholderConfigurer bean you can then update other properties in the security.xml file to reference the values from the file using ${name} as a place holder to the property value, e.g.

<bean id="initialDirContextFactory" class="org.acegisecurity.ldap.DefaultInitialDirContextFactory">
	<constructor-arg value="ldap://10.0.12.213:389/" />
	<property name="managerDn">
		<value>CN=Administrator,CN=Users,DC=adel,DC=cohga,DC=com</value>
	</property>
	<property name="managerPassword">
		<value>${password}</value>
	</property>
</bean>

Here the managerPassword value will be taken from the password value stored in the security.properties file.

As mentioned earlier any value can be replaced with a value from the properties file, so if you didn't want to have a username visible in the file you could also store that value in the properties file.

Also, the values in that file don't have to be encrypted, if you just want to store values in an external file, for example if you want to have the same security.xml file in a test and production servers but they both reference different values you could also store those values in an external properties file and reference them in security.xml instead.

If you don't need the values to be encrypted at all you could just use the org.springframework.beans.factory.config.PropertyPlaceholderConfigurer bean and don't bother to set the key property.