(Mini-Howto contributed by Peter Viglucci)
Make sure you include references to Jasypt and its dependencies in your project. Check the dependencies page for details on the specific jar files to be added.
Make Seam aware that you are using Jasypt by adding the following to application.xml:
<!-- Jasypt and dependencies --> <module> <java>jasypt-1.9.2.jar</java> </module> <!-- ICU4J not needed if you are using Java 6 or higher --> <module> <java>icu4j-3.4.4.jar</java> </module>
You will need to make these jars available to JBoss as well. Either copy them to the server's lib directory or make sure they are part of the ear file when the app is deployed. If you used seam-gen to generate the skeleton for the application then modify the ear target in the build.xml file to include the jars.
The Jasypt page on Hibernate 3 integration details the steps. Here is a simple example. Imagine you have a Person class with an ssn string field you want to store encrypted. The class will look something like this:
package entity.Person; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.GeneratedValue; import javax.persistence.Version; import org.jboss.seam.annotations.Name; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; import org.hibernate.annotations.Parameter; import org.hibernate.validator.Length; import org.jasypt.hibernate3.type.EncryptedStringType; @TypeDef( name="encryptedString", typeClass=EncryptedStringType.class, parameters={@Parameter(name="encryptorRegisteredName", value="myHibernateStringEncryptor")} ) @Entity @Name("person") public class Person implements Serializable { private static final long serialVersionUID = -2082341992912047209L; private Long id; private Integer version; private String firstName; private String lastName; private String ssn; @Id @GeneratedValue public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Version public Integer getVersion() { return version; } @SuppressWarnings("unused") private void setVersion(Integer version) { this.version = version; } @Length(max=20) public String getFirstName() { return firstName; } public void setFirstName(String name) { this.firstName = name; } public void setLastName(String lastName) { this.lastName = lastName; } public String getLastName() { return lastName; } public void setSsn(String ssn) { this.ssn = ssn; } @Type(type="encryptedString") public String getSsn() { return ssn; } }
Notice that we use simple annotations to define the Hibernate mapping. Also notice the imports you'll need to define in order for this to work.
This was a problem in earlier version of Seam because there was not an easy way to run code when the application was initialised. Seam 2 solves this problem by providing the postInitialization event. The postInitialization event fires right after Seam has initialised and started up all components. This provides the perfect place to stick the code that provides the encryptor to Hibernate.
To make use of the event, we simply define a class with a method that acts as an observer of the event. Basically, the server is started, right after Seam finishes initializing the event fires, our code gets run. Here is a simple class called Initializer that does the work:
package session; import org.jasypt.encryption.pbe.StandardPBEStringEncryptor; import org.jasypt.encryption.pbe.config.EnvironmentPBEConfig; import org.jasypt.hibernate3.encryptor.HibernatePBEEncryptorRegistry; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Observer; import org.jboss.seam.annotations.Logger; import org.jboss.seam.log.Log; @Name("initializer") public class Initializer { @Logger Log log; @Observer("org.jboss.seam.postInitialization") public void initializeJasypt() { log.info("Initializing Jasypt String Encryptor"); StandardPBEStringEncryptor strongEncryptor = new StandardPBEStringEncryptor(); EnvironmentPBEConfig config = new EnvironmentPBEConfig(); config.setPasswordEnvName("jasypt_password"); strongEncryptor.setConfig(config); HibernatePBEEncryptorRegistry registry = HibernatePBEEncryptorRegistry.getInstance(); registry.registerPBEStringEncryptor("myHibernateStringEncryptor", strongEncryptor); } }
There are a few things going on here:
First set the variable that EnvironmentPBEConfig is expecting:
# export jasypt_password="mysecretpassword"
Start the server in the background so we can get back to the prompt:
# run.sh &
Wait for the server to start up. Look for the logging message indicating that the code actually ran. After the startup is complete, unset the environment variable.
# unset jasypt_password
If all went well then the ssn field will be stored encrypted in the DB!