In real-world applications, we typically store an environment-specific configuration outside of the application, and access it through the properties mechanism described in the Using external properties in Camel routes recipe in Chapter 1, Structuring Routes. This enables us to move an application between development, test, and production environments with no code changes required to repoint it to different databases, message brokers, and so on.
To access these resources we often need to store sensitive information such as passwords. It is considered bad practice to keep these in plain text, as that would allow the reader to freely access those resources. To address this, we need to overlay another mechanism that allows us to hide passwords through encryption.
This recipe will show you how to use the Camel Jasypt Component to manage encrypted configuration values within Camel.
The Java code for this recipe is located in the org.camelcookbook.security.encryptedproperties
package. The Spring XML files are located under src/main/resources/META-INF/spring
and prefixed with encryptedProperties
.
To use the Camel Jasypt Component, add the following to the dependencies
section of your Maven POM:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jasypt</artifactId> <version>${camel-version}</version> </dependency>
To encrypt passwords you will also require access to the camel-jasypt
JAR file. This file can be found in the binary download of the Camel distribution in the lib
directory.
To encrypt configuration properties, perform the following steps:
lib
directory of the location that you just extracted Camel into:# java -jar camel-jasypt-2.12.2.jar -c encrypt -p encryptionPassword -i myDatabasePassword
The -c
flag denotes the task to be performed (encrypt/decrypt). The -p
argument is the password used to encrypt the property that you wish to hide. The -i
argument is the input that is to be encrypted. The encrypted version of the database password is printed out:
Encrypted text: hRR5B31qPMJpxk078rXmwllpzQNPpR5kXdnNQrOmIfs=
ENC(..)
string to denote encryption:start.endpoint=direct:in
log.message=The database password is {{database.password}}
database.password=ENC(hRR5B31qPMJpxk078rXmwllpzQNPpR5kXdnNQrOmIfs=)
end.endpoint=mock:out
bean
:<bean id="jasypt" class="org.apache.camel.component.jasypt.JasyptPropertiesParser"> <property name="password" value="encryptionPassword"/> </bean>
The password used here is the same as that provided to the -p
argument during the encryption phase in the command line.
Inside the camelContext
element, define a propertyPlaceholder
element that refers to the properties file to be picked up and the parser bean:
<propertyPlaceholder id="properties"
location=
"classpath:placeholder.properties"
propertiesParserRef="jasypt"/>
If using Java only, you need to instantiate the parser and PropertiesComponent
, and set the component on the Camel context before it is started:
JasyptPropertiesParser propParser = new JasyptPropertiesParser(); propParser.setPassword("encryptionPassword"); PropertiesComponent propComponent = new PropertiesComponent(); propComponent.setLocation("classpath:placeholder.properties"); propComponent.setPropertiesParser(propParser); CamelContext camelContext = new DefaultCamelContext(); camelContext.addComponent("properties", propComponent);
The following XML DSL demonstrates this usage:
<from uri="{{start.endpoint}}"/>
<setHeader headerName="dbPassword">
<constant>{{database.password}}</constant>
</setHeader>
<log message="{{log.message}}"/>
<to uri="{{end.endpoint}}"/>
The same route is expressed in the Java DSL as:
from("{{start.endpoint}}")
.setHeader("dbPassword", simple("{{database.password}}"))
.log("{{log.message}}")
.to("{{end.endpoint}}");
In both cases, the route will print out the decrypted string when a message is passed through it:
The database password is myDatabasePassword
The Jasypt Component uses the password that it has been provided with to decrypt any properties that contain the string pattern ENC(..)
using the default algorithm PBEWithMD5AndDES
.
If you want to use a different algorithm, you run the encryption command from the command line, and pass in the algorithm name through its -a
argument. The same algorithm name needs to be passed to the JasyptPropertiesParser
through its algorithm
property.
Algorithm names are defined in the JCE Standard Algorithm Names Documentation. The algorithm used has to be supported by the JCE providers on both the system that you encrypt the password on, and the one that decrypts it. Not all algorithms are available on all JVMs due to export restrictions. For most purposes, the default algorithm is perfectly adequate.
Leaving your master password unencrypted in your code is rarely a good idea. The JasyptPropertiesParser
allows you to pass in the name of a Java system variable, or an environment variable, and resolves the password from that for decryption purposes. To use this mechanism, you prefix the password property as follows:
jasyptMasterPassword
- This resolves a Java system property, set through java –DjasyptMasterPassword=…
when starting the JVM that runs the routesJASYPT_MASTER_PASSWORD
- This resolves to a system variable, set through the shell before the process is startedThe choice of the variable name is up to you; it is only the prefix (sys:
or sysenv:
) that is important.
You often want to use encryption of properties beyond just those used by Camel (for example, passwords for DataSource
objects that are instantiated in Spring). For instructions on how to do this, refer to the Jasypt documentation.
3.15.239.214