start online intellij initializr encrypted spring-boot jasypt

spring-boot - online - spring encrypted properties



Creando una Propiedad de Jasypt personalizada en Springboot (2)

Estoy usando Spring Boot para crear una aplicación web simple que acceda a una base de datos. Aprovecho la funcionalidad de autoconfiguración para DataSource configurando las propiedades de spring.datasource.* En application.properties . Todo eso funciona de manera brillante y fue muy rápido, ¡muchachos de trabajo en la primavera!

La política de mi empresa es que no debe haber contraseñas de texto claras. Por lo tanto, necesito tener la sping.datasource.password encriptada. Después de investigar un poco, decidí crear una implementación org.springframework.boot.env.PropertySourceLoader que crea un jasypt org.jasypt.spring31.properties.EncryptablePropertiesPropertySource siguiente manera:

public class EncryptedPropertySourceLoader implements PropertySourceLoader { private final StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor(); public EncryptedPropertySourceLoader() { //TODO: this could be taken from an environment variable this.encryptor.setPassword("password"); } @Override public String[] getFileExtensions() { return new String[]{"properties"}; } @Override public PropertySource<?> load(final String name, final Resource resource, final String profile) throws IOException { if (profile == null) { final Properties props = PropertiesLoaderUtils.loadProperties(resource); if (!props.isEmpty()) { return new EncryptablePropertiesPropertySource(name, props, this.encryptor); } } return null; } }

Luego empaqué esto en su propio jar con un archivo META-INF/spring.factories la siguiente manera:

org.springframework.boot.env.PropertySourceLoader=com.mycompany.spring.boot.env.EncryptedPropertySourceLoader

Esto funciona perfectamente cuando se ejecuta desde maven usando mvn spring-boot:run . El problema ocurre cuando lo ejecuto como una guerra independiente usando java -jar my-app.war . La aplicación aún se carga pero falla cuando trato de conectarme a la base de datos ya que el valor de la contraseña aún está encriptado. Agregar el registro revela que EncryptedPropertySourceLoader nunca se carga.

Para mí esto suena como un problema de classpath. Cuando se ejecuta bajo maven, el orden de carga del jar es estricto, pero una vez debajo del tomcat embebido no hay nada que decir que mi tarro personalizado debe cargarse antes de Spring Boot.

Intenté agregar lo siguiente a mi pom.xml para asegurarme de que se conserva la classpth, pero parece que no ha tenido ningún efecto.

<build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> <archive> <manifest> <mainClass>${start-class}</mainClass> <addClasspath>true</addClasspath> </manifest> </archive> </configuration> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>

¿Alguien tiene alguna idea? Gracias por adelantado.

ACTUALIZAR:

Un paso adelante: me las he arreglado para hacer que la clase EncryptedPropertySourceLoader implemente la interfaz org.springframework.core.PriorityOrdered y devuelva HIGHEST_PRECEDENCE de getOrder() . Esto ahora ha solucionado el problema de que PropertySourceLoader no se utiliza. Sin embargo, ahora arroja el siguiente error cuando intenta descifrar las propiedades:

org.jasypt.exceptions.EncryptionInitializationException: java.security.NoSuchAlgorithmException: PBEWithMD5AndDES SecretKeyFactory not available at org.jasypt.encryption.pbe.StandardPBEByteEncryptor.initialize(StandardPBEByteEncryptor.java:716) at org.jasypt.encryption.pbe.StandardPBEStringEncryptor.initialize(StandardPBEStringEncryptor.java:553) at org.jasypt.encryption.pbe.StandardPBEStringEncryptor.decrypt(StandardPBEStringEncryptor.java:705) at org.jasypt.properties.PropertyValueEncryptionUtils.decrypt(PropertyValueEncryptionUtils.java:72) at org.jasypt.properties.EncryptableProperties.decode(EncryptableProperties.java:230) at org.jasypt.properties.EncryptableProperties.get(EncryptableProperties.java:209) at org.springframework.core.env.MapPropertySource.getProperty(MapPropertySource.java:36) at org.springframework.boot.env.EnumerableCompositePropertySource.getProperty(EnumerableCompositePropertySource.java:49) at org.springframework.boot.context.config.ConfigFileApplicationListener$ConfigurationPropertySources.getProperty(ConfigFileApplicationListener.java:490)

De nuevo, esto no ocurre cuando se ejecuta desde mvn spring-boot:run pero sucede cuando se ejecuta desde el archivo war ejecutable. Ambos escenarios usan la misma JVM (jdk1.6.0_35). Los resultados en Google / Stackoverflow sugieren que este es un problema con la política de seguridad de Java, pero como funciona cuando se ejecuta desde Maven creo que puedo descartar eso. Posiblemente un problema de empaque ...


Hay dos problemas aquí.

1) El EncryptedPropertySourceLoader necesita cargarse más alto que el PropertiesPropertySourceLoader estándar. Esto se puede lograr implementando la interfaz PriorityOrder de la siguiente manera:

public class EncryptedPropertySourceLoader implements PropertySourceLoader, PriorityOrdered { private final StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor(); public EncryptedPropertySourceLoader() { this.encryptor.setPassword("password"); //TODO: this could be taken from an environment variable } @Override public String[] getFileExtensions() { return new String[]{"properties"}; } @Override public PropertySource<?> load(final String name, final Resource resource, final String profile) throws IOException { if (profile == null) { //load the properties final Properties props = PropertiesLoaderUtils.loadProperties(resource); if (!props.isEmpty()) { //create the encryptable properties property source return new EncryptablePropertiesPropertySource(name, props, this.encryptor); } } return null; } @Override public int getOrder() { return HIGHEST_PRECEDENCE; } }

La clase org.springframework.core.io.support.SpringFactoriesLoader que carga org.springframework.boot.env.PropertySourceLoader de META-INF/spring.factories ordena los resultados utilizando org.springframework.core.OrderComparator . Lo que significa que esta clase debe devolverse primero y se le dará la responsabilidad de proporcionar la implementación de PropertySourceLoader para los archivos * .proerpties.

2) El segundo es un problema de carga de clases con el JAR / WAR ejecutable que parece ser causado por un error en la versión 1.1.2.RELEASE de Spring Boot en Windows. Bajando a la versión 1.1.1.RELEASE o a la versión 1.1.3.RELEASE resuelve los diversos problemas con las clases y archivos de proerpties que no se cargan cuando se ejecutan fuera de maven.


Podría probar esto: jasypt-spring-boot Básicamente, envuelve todos los PropertySource presentes en el entorno con una versión encriptable. Las dos cosas que debes hacer una vez que importas la biblioteca (agregando la dependencia si usas maven) es anotar tu clase @Configuration con @EnableEncryptableProperties, y configurar el algoritmo de encriptación y la contraseña a través de las propiedades.