The requirement:
We have a Java EE (Java 8) monolith that is run with JBoss EAP 7.1 and is using Hibernate as ORM tool. The task is to stop using hardcoded datasource credentials, but to use username and password that are loaded from Vault. The Vault implementation is already in place and the app successfully communicates with it.
We've achieved this in another app, which is Spring-based, in two ways:
- using
spring-cloud-starter-vault-config
library; - using custom implementation that adds a PropertySource with
spring.datasource.username
andspring.datasource.password
with higher priority than the default ones (basically the same thing the library achieves).
The current setup:
persistence.xml
:
...
<persistence-unit name="pu" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/pu</jta-data-source>
<properties>
<property name="hibernate.connection.useUnicode" value="true"/>
<property name="hibernate.connection.characterEncoding" value="UTF-8"/>
<property name="hibernate.jdbc.batch_size" value="20"/>
<property name="hibernate.cache.use_query_cache" value="false" />
<property name="hibernate.cache.use_second_level_cache" value="false" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
</properties>
</persistence-unit>
<persistence-unit name="container-unmanaged" transaction-type="RESOURCE_LOCAL">
... {another persistence unit}
</persistence-unit>
...
standalone.xml
:
<datasource jta="true" jndi-name="java:jboss/datasources/pu" pool-name="pupool" enabled="true" use-java-context="true" use-ccm="false">
<connection-url>{TheConnectionUrl}</connection-url>
<driver-class>org.postgresql.Driver</driver-class>
<driver>postgresql</driver>
<pool>
<min-pool-size>2</min-pool-size>
<max-pool-size>20</max-pool-size>
</pool>
<security>
<user-name>{TheUserName}</user-name>
<password>{ThePassword}</password>
</security>
<validation>
<validate-on-match>false</validate-on-match>
<background-validation>true</background-validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker"/>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter"/>
<background-validation-millis>5000</background-validation-millis>
</validation>
<statement>
<prepared-statement-cache-size>0</prepared-statement-cache-size>
<share-prepared-statements>false</share-prepared-statements>
</statement>
</datasource>
In other words, I want to get rid of <user-name>
and <password>
from the standalone.xml
configuration, and provide those at runtime (having already loaded them from Vault).
What's been tried:
I've reviewed multiple questions and articles, expecting that what I'm trying to do would be fairly simple, or at least that many others have been looking for a solution, but none of the suggestions seem to work. For example:
- the requirement here seems like what I need, but the credentials should be provided by the app, at runtime;
- this article also seems very similar, but when I try to implement it, it looks like the login module mentioned there should be used for users of the app to login. Anyway, I couldn't get it to work;
- I've also reviewed and tried to implement Vlad Mihalcea's article on how to bootstrap w/o replying on persistence.xml file. However, I'm not trying to substitute the whole file, but rather just intercept it at runtime, add the credentials and let it do its work. And what is more, I couldn't add the
hibernate.datasource.username
andhibernate.datasource.password
to theproperties()
provided at runtime; I get theThe server requested password-based authentication, but no password was provided.
message (of course after removing the credentials fromstandalone.xml
).
Note: I don't want to encrypt the password, but provide it programmatically at runtime.
So, is there a way to do it just like in Spring, or should it be done differently?
Thanks!