Apache Cayenne keeps a "...project.xml" file within the resources directory. This file contains the password to the database. This is a problem because the [deployment server] password should not visible to developers. Further, it would need to be a different user/password and connection to a different database during development.
What is the best practice to manage this "...project.xml" when using Cayenne? Any suggestions?
EDIT:
Instead of putting the database connection info (incl. password) into the XML file, is it possible to inject the info programatically into the DataSource object? If so, I can load the info from a config file when the app starts and then inject it.
Yes of course. There is a "cayenne.jdbc.password" property that can be used to define DataSource password in runtime. It can be applied in two alternative ways:
As a system property on command line:
java -Dcayenne.jdbc.password=xxxxx
Via injection:
ServerModule.contributeProperties(binder)
.put(Constants.JDBC_PASSWORD_PROPERTY, "xxxxx");
This and other config properties are documented here.
Related
everyone!
this is going to be my first time pushing a newly developed Spring Boot App and I was wondering if there is a way to protect passwords and other sensitive information written in the application.properties file.
Assuming we have the following lines:
# PostgreSQL connection settings
spring.datasource.jdbc-url=jdbc:postgresql://localhost:5432/bdreminder
spring.datasource.username=username
spring.datasource.password=password
The source code is to be first stored on GitHub and having the credentials stored in plain text does not seem to be a good idea.
So, I could probably add the file to the .gitignore one; I could set some environment variables on the host but how would it populate the .properties file afterward? Also, this seems quite cumbersome in terms of the scaling later on.
So, basically, I am trying to see how it is done in a real-life :)
Please, help :)
Simplest option is to create a profile specific application.properties file and activate that profile. So for example create application-private.properties and activate profile private. Of course you have to watch out to not commit this file.
Alternatively, and probably a safer option, is to define a file outside your project and import it in your application.properties with following line:
spring.config.import=file:../path/to/your/external.properties
Spring Boot has extensive support for external configuration. The usual approach is to use one of environment variables, configuration provided by a platform such as Kubernetes, or a specialized configuration system through Spring Cloud Config; these all keep secrets (or just environment-specific information) entirely outside of the code. They also have the advantages of providing a common style of configuration for other applications that do not use Spring Boot.
I've been searching for a way to avoid hard coding my database credentials into my code base (mainly written in Java), but I haven't found many solutions. I read this post where they said a one way hash could be the answer. Is there another way of securely connecting to a database without running into the risk of someone decompiling your code?
Just to clarify, I'm not looking for code, rather a nudge in the right direction.
If you can used spring boot application, then you can configure using cloud config method. I have added some postgresql db connection details for your further reference. Please refer following link for spring boot cloud config. spring_cloud
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://{{db_url}}:5432/{{db_name}}
spring.datasource.username=postgres
spring.datasource.password=
spring.datasource.maxActive=3
spring.datasource.maxIdle=3
spring.datasource.minIdle=2
spring.datasource.initialSize=2
spring.datasource.removeAbandoned=true
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=3
spring.datasource.tomcat.test-on-borrow=true
You could load a config file in your code. Define some kind of file, such as JSON or XML, and define all of your configurations in there. You could point to the file as a command line argument, or just hardcode the file path.
Here's a post talking about parsing JSON config in Java:
How to read json file into java with simple JSON library
You can refer to these post. They are basically just saying to either hash, store it in a property file or use an API. Some of the posts are not merely on Java but you can get ideas from them.
How can I avoid hardcoding the database connection password?
https://security.stackexchange.com/questions/36076/how-to-avoid-scripts-with-hardcoded-password
https://www.codeproject.com/Articles/1087423/Simplest-Way-to-Avoid-Hardcoding-of-the-Confidenti
The solution in our team, database as a service,other application use it's API to get database credentials,the request contains simple credentials like application name.
You have several options to avoid hard code values in your source code:
Properties using Advanced Platforms
Properties from Environment variables
Properties from SCM
Properties from File System
More details here:
https://stackoverflow.com/a/51268633/3957754
This is fairly straight forward with a simple Spring DAO approach. However, using MyBatis, is there a way to setup multiple potential datasources?
The best approach I can think of is to use an ArraList of a Bean each containing datasource.driverclass,datasource.url, datasource.username, datasource.password etc.
The values for the datasources are stored in individual properties files. There could be 1 or 10 of these property files (or more).
So for example, one application startup all the property files would be loaded one at a time into an ArrayList. Then, based on the NAME=value line from the property file, we would know which datasource to hit.
So http:localhost:8080/name=db1
... would access all the data from the datasource configured with the name "09". Each property file would contain:
name=db1
datasource.driverclass=jdbc:sqlserver
datasource.url=jdbc:sqlserver://localhost:1433;databaseName=someDBname
datasource.username=user1
datasource.password=pass1
So the identifier here is "name=db1".
Would the best approach from a MyBatis implementation utilise an ArrayList of Beans?
Here are some leads if you want to keep up with multiple DB:
Anyway, I would say datasources shall be managed in the server confiquration instead of in the App.
Then Mybatis main configuration file must be placed in a location added to the classpath, but outside of the app package, because every new datasource must be referenced there inside an environment element.
And for every user request or session (in case of a web app), the configuration will be parsed because SqlSessionFactoryBuilder.build(reader, environment=NAME); must be called to choose the environment (=> the DB).
I ended up using a hierarchical application.yml file detailing the multitenant connection values, based on a selected tenant code.
The problem with hibernate is, you need to put the database info (username/pw etc) in an xml file. However, if you deploy your app on Amazon web services, e.g on Beanstalk, you get the db info passed in via System.getProperty("RDS_DATABASE_USER"), etc. The advantage is, if more instances of your app are created, the db info is passed on automatically, without having to manually edit config files.
Is there a way to pass the db info to hibernate at runtime? If not, is there another good ORM library for java, to which you can pass this info at runtime? I'm using MySQL.
As a matter of fact, the method PersistenceUtil.createEntityManagerFactory allows you to provide a properties map. Using this map you can provide the user name and password in dynamic way.
How you do this may well depend on what specific frameworks you are using.
Based on the tags in your question it is not clear if you are using Hibernate or if you are using OpenJPA.
The Open JPA documentation in the section Obtaining an EntityManagerFactory provides the list of properties you could use.
Map<String,String> properties = new HashMap<>();
properties.put("openjpa.ConnectionUserName", "userName");
properties.put("openjpa.ConnectionPassword", "password");
EntityManagerFactory emf = Persistence.createEntityManagerFactory("MyPersistenceUnit",properties);
Hibernate supports a similar set of properties. Most probably you already have them in your persistence.xml file.
Some dependency injection frameworks, like Spring, don't even require a persistence.xml file and can read such properties dynamically from some other places, like environment variables.
Is there a way to ask for the database password at runtime instead of putting it (encrypted or not) in the hibernate.cfg.xml file?
Just about every configuration option in Hibernate has a corresponding method on the object being configured. In reality, the configuration is really just a way to bind XML to the objects being set up. See this article for more information: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html
That said, the onus is on you to collect the password at startup. That can be the most difficult part of the problem. Once you've collected the password, send it to the appropriate property.
Usually the best way to do it, if you're using a Java EE app server, is to use a JNDI look up to get the database connection instead of using a driver manager. That way the person who sets up the JNDI connection pool is the only one that has to know the password, and it's generally encrypted in the admin console so it's safe.
I think if you are using programmatic instantiation of the Hibernate configuration, you can initialize it from the configuration file that does not contain a password, set the additional property for the database connection on the configuration object you're instantiating, then call buildConfguration().