application connect to database - java

I am working on an application that will be used by schools. Each school will set up their on database. And each school will provide their own "settings" file to the application. The settings file will contain the database url for the specific school who made the settings file. This is so that a student using the application can just load a different settings file if they want to connect to a different database.
My question is, how do i protect the username and password used to connect to the database? So, that ONLY the application has read and write access to the database. And the application has read and write access to only that specific school?
If you need more information, please let me know.
Thanks

Take a look at Jasypt, it is a java library which allows the developer to add basic encryption capabilities to his/her projects with minimum effort, and without the need of having deep knowledge on how cryptography works.
In case you use Spring, you can define your db.properties as:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/yourdb
jdbc.username=userName
jdbc.password=ENC(A6L729KukPEx7Ps8didIUWb01fdBRh7d)
and configure it with Jasypt and Spring as:
<bean class="org.jasypt.spring.properties.EncryptablePropertyPlaceholderConfigurer">
<constructor-arg>
<bean class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<property name="config">
<bean class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
<property name="algorithm" value="PBEWithMD5AndDES" />
<property name="passwordEnvName" value="APP_ENCRYPTION_PASSWORD" />
</bean>
</property>
</bean>
</constructor-arg>
<property name="locations">
<list>
<value>classpath:/META-INF/props/db/db.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
This would hide the actual password (you can do the same for the username) from students, so they would not be able to derive the connection string from looking at the properties file.
In case you are not using Spring, here is a Jasypt guide to achive the same "manually"

Related

Create database script mySQL

I have dynamic web java project where I am using spring-MVC/hibernate. In my xml config file I have a bean for setting up my sessionFactory (all dependencies - jdbc url etc. for my local database). Is there a way I can send this project + database to my friend and it will work ? I am wondering because in xml config file I have the exact jdbc url, hostname, port etc. which doesnt have to be the same on my friend's laptop but is there a way to create some script that will create database with the exactly same properties as my local database ?
EDIT - here is config file
<!-- Define Database DataSource / connection pool -->
<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/java_task?useSSL=false" />
<property name="user" value="me" />
<property name="password" value="me" />
<!-- these are connection pool properties for C3P0 -->
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="20" />
<property name="maxIdleTime" value="30000" />
</bean>
<!-- Define Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan" value="com.javatask.entity" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
[...] is there a way to create some script that will create database
with the exactly same properties as my local database?
In the hibernate-tools jar, Hibernate provides a SchemaExport tool that supports what you want to do.
You can write a little program yourself to use it, but I think most folks don't "roll their own." I think it's common to use a plugin for your build system.
Are you using Maven? You could use something like this: https://github.com/Devskiller/jpa2ddl
Is there a way I can send this project + database to my friend and it
will work ?
Yes, u can put your code in a public repository like Github, and ur friend can clone it from there
I am wondering because in xml config file I have the exact jdbc url,
hostname, port etc. which doesnt have to be the same on my friend's
laptop but is there a way to create some script that will create
database with the exactly same properties as my local database ?
We don't know ur code, but if u have provided absolute path in ur configuration then it will fail in ur friend's laptop. For a better answer, please provide ur configuration code
You can read about absolute path here
Update
I don't see any problem in your config code. it should work well in another system. About uploading the database, u can simply export it from ur database, and put the deattached file into the folder of ur current project. Once u push ur code to the repo the database would be there too. Then the other person, will get it again by the other codes. Again there is no problem.
Your firend must get sure that he has Mysql, and it is working on port 3306. But, there shouldn't be any problem. why do u think, it would fail?

JAVA + PostgreSQL + Spring

I want to use Spring to connect to my local PostgreSQL db. I don't know if it is possible, cause I didn't find any tutorials for this. So is it possible? If yes, please explain me where can I find some fine tutorial. If no, how can I do it? I know I can make it via postgresql jdbc, but I want to do it like in real company.
Of course you can. The database vendor is immaterial. Java hides database details using JDBC.
Here is a Spring tutorial that shows you how to do it in 15 minutes or less.
First you need to create a spring project from https://start.spring.io/ and add postgresql to its dependencies. You will then see it build up in your pom.xml file. Then you have to enter the information of the postgresql database you want to connect to in the application.yml file.
Here is my example.
applicationContext.xml :
<!-- the setting msg -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config/database.properties</value>
</list>
</property>
</bean>
<!-- PostgreSQL datasource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- ibatis client -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:config/SqlMapConfig.xml" />
<property name="dataSource" ref="dataSource" />
</bean>

Get database information at runtime

In my web application (spring + tomcat), below is by applicationContext.xml. All the database information (username, password) is currently directly embedded. But now in our application, the server forks a new JVM instance and this new JVM instance needs to communicate with the same database.
<bean id="meetingDBSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:initialSize="10" p:maxActive="50" p:minIdle="5"
p:maxIdle="35" p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://10.0.1.100/warehouse_mon?useLegacyDatetimeCode=false&useUnicode=true&serverTimezone=UTC&"
p:username="user" p:password="pass" p:testOnBorrow="true"
p:validationQuery="SELECT 1" />>
<bean id="appDB" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="meetingDBSource" />
</property>
</bean>
So I wish to pass the required information as arguments while launching it. Now what is the dignified way of getting this database information?
Initially in my applicationContext.xml, I made a map and inserted all the db information in the map. Using Spring special expressions, I was obtaining the values and then using them for BasicDataSource initialization. And in my code, using dependency injection I obtained access to this map and then obtained information.
But I guess there should be a more standard factory way of doing it. (Or probably using context-param and if so, how?)
I use it like this.
I have a database.properties file like this.
db.driverClassName=com.mysql.jdbc.Driver
db.connectionUrl=jdbc:mysql://localhost:3306/test
db.username=test
db.password=testpass
sql.use.db.data=false
sql.use.db.test.data=false
Then in applicationContext.xml I will configure
<!--property place holder bean -->
<bean id="propertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="ignoreResourceNotFound" value="false"/>
<property name="locations">
<list>
<value>classpath:/properties/database.properties</value>
</list>
</property>
Then datasource is configured like this
<!-- data source bean-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driverClassName}"/>
<property name="url" value="${db.connectionUrl}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</bean>
You can use #Value annotation to access the properties in that file.
#Value("${sql.use.db.data}")
private String use_data;

How can you connect to a password protected MS Access Database from a Spring JdbcTemplate?

I need to connect to a password protected MS Access 2003 DB using the JDBC-ODBC bridge. I can't find out how to specify the password in the connect string, or even if that is the correct method of connecting.
It would probably be relevant to mention that this is a Spring App which is accessing the database through a JdbcTemplate configured as a datasource bean in our application context file.
Some relevant snippets:
from application-context.xml
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="legacyDataSource" />
</bean>
<bean id="jobsheetLocation" class="java.lang.String">
<constructor-arg value="${jobsheet.location}"/>
</bean>
<bean id="legacyDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.legacy.driverClassName}" />
<property name="url" value="${jdbc.legacy.url}"/>
<property name="password" value="-------------" />
</bean>
from our build properties
jdbc.legacy.driverClassName=sun.jdbc.odbc.JdbcOdbcDriver
jdbc.legacy.url=jdbc:odbc:Driver\={Microsoft Access Driver (*.mdb)};Dbq\=#LegacyDbPath#;DriverID\=22;READONLY\=true
Any thoughts?
try appending your url with
UID\=user;PWD\=pwd

How to collect spring properties from multiple files for use on a single bean

I haven't gotten my head wrapped around Spring yet, so correct me if this question doesn't make sense...
I have a PropertyPlaceholderConfigurer
<bean id="rdbmPropertiesPlacholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" lazy-init="false">
<property name="location" value="classpath:/properties/rdbm.properties" />
</bean>
And I have a bean being injected I guess?
<bean id="PortalDb" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${hibernate.connection.driver_class}" />
<property name="url" value="${hibernate.connection.url}" />
<property name="username" value="${hibernate.connection.username}" />
<property name="password" value="${hibernate.connection.password}" />
...
What I want is a second placeholder pointing to a different properties file with the username/password so that I can split up the properties into two different files. Then the database connection information can be separate from the db username/password, and I can source control one and not the other.
I've tried basically copying the rdbmPropertiesPlaceholder with a different id and file and trying to access the properties, but it doesn't work.
This code is from the uPortal open source web portal project.
Using this notation lets you specify multiple files:
<bean id="rdbmPropertiesPlacholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" lazy-init="false">
<property name="locations">
<list>
<value>classpath:/properties/rdbm.properties</value>
<value>classpath:/properties/passwords.properties</value>
</list>
</property>
</bean>
The propertyplaceholderconfigurerer just merges all of these to look like there's only one, so your bean definitions do not know where the properties come from.
The org.springframework.beans.factory.config.PropertyPlaceholderConfigurer can do this (as already answered. What you may want to do is make use of the name spacing so that you can refer to same-named properties from both files without ambiquity. For your example, you can do this:
<bean id="generalPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:/properties/general.properties"/>
</bean>
<bean id="db.PropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:/properties/rdbm.properties" />
<property name="placeholderPrefix" value="$db{" />
<property name="placeholderSuffix" value="}" />
</bean>
In your context files, you can now refer to general properties with ${someproperty}, and refer to rdbm properties with $db{someproperty}.
This will make your context files much cleaner and clearer to the developer.

Categories