the org dbcp2 dbcp connectionfactory component commons basicdatasourcefactory basicdatasource spring hibernate datasource apache-commons-dbcp password-encryption

spring - dbcp2 - org apache commons dbcp connectionfactory



Uso de contraseƱa codificada para el origen de datos utilizado en spring applicationContext.xml (5)

Cree PropertyPlaceHolderConfigurer personalizado extendiendo Spring PropertyPlaceHolderConfigurer

public class PropertyPlaceholderConfigurer extends org.springframework.beans.factory.config.PropertyPlaceholderConfigurer { @Override protected String convertPropertyValue(final String originalValue) { if (originalValue.startwith("SomeText:")) { //Apply the decryption logic ... } } }

Puede cifrar las propiedades y adjuntar SomeText:. Utilice este PropertyPlaceHolderConfigurer personalizado para cargar las propiedades

Quiero mantener la contraseña codificada en mi springApplicationContext.xml mencionado a continuación

¿Hay alguna manera de lograr esto?

Actualmente, he configurado todas las propiedades utilizando el marcador de posición de propiedad como se muestra a continuación, pero la contraseña sin procesar aún está abierta en mi base de datos.properties

springApplicationContext.xml

<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <beans:property name="driverClassName"><beans:value>${db.driverClassName}</beans:value></beans:property> <beans:property name="url"><beans:value>${db.url}</beans:value></beans:property> <beans:property name="username"><beans:value>${db.username}</beans:value></beans:property> <beans:property name="password"><beans:value>${db.password}</beans:value></beans:property> </beans:bean>

pero los valores reales están presentes en mi database.properties

db.driverClassName=com.mysql.jdbc.Driver db.url=jdbc:mysql://localhost/myDB db.username=root db.password=root

Quiero algo como a continuación:

springApplicationContext.xml (igual que arriba)

<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <beans:property name="driverClassName"><beans:value>${db.driverClassName}</beans:value></beans:property> <beans:property name="url"><beans:value>${db.url}</beans:value></beans:property> <beans:property name="username"><beans:value>${db.username}</beans:value></beans:property> <beans:property name="password"><beans:value>${db.password}</beans:value></beans:property> </beans:bean>

Pero el valor de la propiedad de la contraseña debe estar en formato encriptado en mi database.properties datos.properties

db.driverClassName=com.mysql.jdbc.Driver db.url=jdbc:mysql://localhost/myDB db.username=root db.password=3g6n72ef8x (using any encription method).

y mi fuente de datos descifra internamente la contraseña antes de establecer una nueva conexión de base de datos.

Muy apreciado por cualquier ayuda / sugerencia en esto.


Cree una clase contenedora que implemente la interfaz de la Datasource , que delega las llamadas de su método a la fuente de datos subyacente, pero descifra la contraseña antes de hacerlo.


Me gustaría ver la imagen más grande aquí: ¿por qué quiere cifrar los valores en su archivo de propiedades? ¿Cuál es su escenario en el que personas no autorizadas tienen acceso a su archivo de propiedades?

Una técnica habitual para lidiar con este problema mayor de almacenar las credenciales de producción es hacer que las credenciales sean parte de su entorno en lugar de parte de su código fuente. Aquí hay algunas maneras de hacer esto:

  • Al colocar el archivo de propiedades (con contraseñas de texto simple) en la ruta de clase del servidor web en producción, de esta manera el acceso a esa contraseña se controla mediante el acceso a la máquina de producción.
  • Almacene las propiedades en web.xml (context-param con param-name), nuevamente este archivo es parte del entorno en el que ejecuta su código y no se distribuye con su código: el acceso a ese archivo se controla mediante el acceso a la máquina.
  • Use JNDI y configure ese recurso en su servidor de aplicaciones.

Puede ser gracioso que esté respondiendo a mi propia pregunta. pero aún así solo quería decirle a mi solución, otras personas que podrían haber enfrentado el mismo tipo de problema ...

Para simplificar, he usado BASE64Encoder y BASE64Decoder. más tarde modificaré mi código para usar un algoritmo de cifrado / descifrado seguro / mejor.

He codificado la contraseña de mi base de datos (por ejemplo, la raíz de mi caso) utilizando el siguiente código:

private String encode(String str) { BASE64Encoder encoder = new BASE64Encoder(); str = new String(encoder.encodeBuffer(str.getBytes())); return str; }

y colocé la contraseña codificada en mi archivo database.properties como a continuación:

antes de

db.driverClassName=com.mysql.jdbc.Driver db.url=jdbc:mysql://localhost/myDB db.username=root db.password=root

después

db.driverClassName=com.mysql.jdbc.Driver db.url=jdbc:mysql://localhost/myDB db.username=root db.password=cm9vdA== (Note: encoded ''root'' by using BASE64Encoder)

Ahora he escrito una clase contenedora para org.apache.commons.dbcp.BasicDataSource y el método setPassword () anulado:

import java.io.IOException; import org.apache.commons.dbcp.BasicDataSource; import sun.misc.BASE64Decoder; public class MyCustomBasicDataSource extends BasicDataSource{ public CustomBasicDataSource() { super(); } public synchronized void setPassword(String encodedPassword){ this.password = decode(encodedPassword); } private String decode(String password) { BASE64Decoder decoder = new BASE64Decoder(); String decodedPassword = null; try { decodedPassword = new String(decoder.decodeBuffer(password)); } catch (IOException e) { e.printStackTrace(); } return decodedPassword; } }

De esta manera estoy decodificando (BASE64Decoder) la contraseña codificada proporcionada en database.properties

y también modifiqué el atributo de clase de mi dataSource bean mencionado en el archivo springApplicationContext.xml.

<beans:bean id="dataSource" class="edu.config.db.datasource.custom.MyCustomBasicDataSource" destroy-method="close"> <beans:property name="driverClassName"><beans:value>${db.driverClassName}</beans:value></beans:property> <beans:property name="url"><beans:value>${db.url}</beans:value></beans:property> <beans:property name="username"><beans:value>${db.username}</beans:value></beans:property> <beans:property name="password"><beans:value>${db.password}</beans:value></beans:property>

Gracias.


Si está utilizando un grupo de conexiones tomcat como fuente de datos, aquí hay una implementación

http://www.jdev.it/encrypting-passwords-in-tomcat/

Cree una clase que amplíe org.apache.tomcat.jdbc.pool.DataSourceFactory y configúrela en el server.xml