Archive for the ‘Hibernate’ Category

h1

Limitaciones de la API Criteria de Hibernate

19 marzo 2010

En el trabajo estoy utilizando la API Criteria para desarrollar un generador de informes, porque permite componer consultas dinámicamente sin tener que concatenar asquerosamente un montón de cadenas de texto. Por desgracia, aún tiene varias limitaciones que no están presentes si utilizamos HQL y que la deslucen un poco.

Lo peor de todo es que descubrirlas puede llevar bastante tiempo, así que por si Google indexa este post de manera que salga en alguna de las primeras entradas, al menos le habrá ahorrado tiempo a alguien xD Las limitaciones que he descubierto hasta ahora son:

  • Cruzar varias veces con la misma tabla (aunque a cada join se le asigne un alias distinto).
  • Restricciones/proyecciones con atributos multivaluados, representados mediante una CollectionOfElements. Para la versión 3.5.0 parece posible que al menos la primera parte del problema se solucione gracias a un parche.
Anuncios
h1

Encriptar la contraseña de conexión en hibernate.cfg.xml

5 febrero 2010

Por defecto, en el fichero de configuración de Hibernate se muestran en texto plano todos los datos de conexión, lo que evidentemente no resulta muy seguro en cuanto lo ponemos a disposición de los usuarios. Para encriptarlos de manera sencilla podemos utilizar la biblioteca Jasypt (Java Simplified Encryption), que también nos permite encriptar el contenido de la base de datos, aunque eso queda fuera del alcance de este post 🙂

En este caso, supongamos que solo vamos a encriptar la contraseña. Lo primero es generar este valor a partir de una clave mediante uno de los scripts BAT o SH que se incluyen en la distribución. Ejecutamos la orden encrypt.bat input=contraseña_a_encriptar password=clave_del_algoritmo y nos devolverá un resultado como el siguiente:

----ENVIRONMENT-----------------
Runtime: Sun Microsystems Inc. Java HotSpot(TM) Client VM 14.2-b01
----ARGUMENTS-------------------
input: mipass
password: foobar
----OUTPUT----------------------
j1BNruKrxJ9xy9u8e1GtBw==

El valor de salida será el que se escriba en el fichero hibernate.cfg.xml, pero antes nos quedan cosas por hacer. En el fichero donde esté mapeada la base de datos (en caso de usar anotaciones habrá que crear uno nuevo) incluimos la declaración del tipo del cifrador:

<hibernate-mapping>
      <typedef name="encrypted"
      class="org.jasypt.hibernate.type.EncryptedStringType">
            <param name="encryptorRegisteredName">
                  hibernateEncryptor</param>
      </typedef>
</hibernate-mapping>

En la clase donde se cree la SessionFactory de Hibernate (lo habitual es utilizar una llamada HibernateUtil) se asocia esta al cifrador antes declarado:

config = new AnnotationConfiguration().configure();

PBEStringEncryptor encryptor =
      new StandardPBEStringEncryptor();
// La clave se puede obtener consultar en web,
// en una variable del programa o de entorno...
encryptor.setPassword("foobar");
HibernatePBEEncryptorRegistry registry =
      HibernatePBEEncryptorRegistry.getInstance();

// Asignar el mismo nombre que en hibernate-mapping
registry.registerPBEStringEncryptor(
      "hibernateEncryptor", encryptor);

sessionFactory = config.buildSessionFactory();

Y ya es hora de tocar el fichero de configuración de Hibernate, añadiendo las siguientes líneas. Es importante escribir la contraseña encriptada entre paréntesis porque es el formato que utiliza Jasypt para diferenciar las cadenas encriptadas de las que viajan en plano.

<!-- Proveedor más simple de conexión encriptada,
también existe uno sobre C3P0 -->
<property name="connection.provider_class">
      org.jasypt.hibernate.connectionprovider.EncryptedPasswordDriverManagerConnectionProvider
</property>
<property name="connection.encryptor_registered_name">
      hibernateEncryptor
</property>
<property name="connection.password">
      ENC(j1BNruKrxJ9xy9u8e1GtBw==)
</property>

<!-- Fichero con el hibernate-mapping -->
<mapping resource="mapping.xml" />

Y con estos pocos pasos habremos mejorado un poquito la seguridad de nuestra aplicación 😀