I have a war file in which a class calls a MySQL DB from Java and thus has the MySQL login information in plain text in the source code. Obviously, for security resons, I don't want this visible to the outside world. The question is thus if the source code in a war file deployed on Tomcat is visible to the outside world?
It's not a problem but not flexible. More usefull to use JNDI. In context.xml put something like this:
<Resource
name="jndi_name_for_datasource"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
testOnReturn="true"
validationQuery="select 1 from dual"
timeBetweenEvictionRunsMillis="30000"
minIdle="1"
initialSize="1"
minEvictableIdleTimeMillis="30000"
username="solaris"
password="super"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:#localhost:1521:slife"
/>
and use lookup fo JNDI name
No it wont be visible. Provided there is no way to download war- Once war is downloaded- Anyone can locate the class and decompile it to see the password.
Better option would be to configure DataSoure - which is outside of your war.
But I think it is still a security issue, if anybody else is having access to tomcat server. e.g. other employees or administrators.
I would suggest you to add simple encryption/decryption technique in the code to prevent others to figure out the password.
Related
I need some help with the Context.xml file in my Java Web Application in Netbeans.
My task was to get my Web App to connect to and display products from my SQL database. I got it to work but I really need help understanding this code:
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver"logAbandoned="true" maxActive="100" maxIdle="30" maxWait="10000" name="jdbc/project" password="" removeAbandoned="true" removeAbandonedTimeout="60" type="javax.sql.DataSource" url="jdbc:mysql://localhost:3306/projinvoice?zeroDateTimeBehavior=convertToNull" username="root"/>
Could anyone tell me what name="jdbc/project" is? Where does this link to?
If I change the name then the Web App does not display my products. How did it get set to jdbc/project and where can I find it?
I did try and use Glassfish to create a JDBC Resource where I could have used that name but it does not show up?
Any help would be appreciated.
Regards
Context.xml is a configuration file for the container. Glassfish and Tomcat for example are using this file.
It declaratively configures the DataSource object in this case. At startup of the web-application, the container will instantiate this object and exposes it through JNDI.
JNDI is a mechanism to look for objects in the VM by name.
So somewhere on your web-app classes, this name is used to fetch this DataSource object. Have a search!
Hoping that someone can clear up a few things -
For a project I need to be able to switch between a Sybase and an Oracle database. Using Spring I have been to come up with a solution using AbstractRoutingDataSource to allow switching between the sybase and oracle data source as needed.
However, within my tomcat context.xml, I have listed all data sources - so for each one I have "jdbc/myDbSybaseDataSource" and "jdbc/myDbOracleDataSource". I was wondering, does tomcat attempt to create all of these data sources on start up, or does it wait until something in the code has invoked it?
I know in spring you can lazy load your beans, but would tomcat still create each resource in the context.xml anyways?
Any help is much appreciated!
Edit
The reason for asking is - if for example, the Sybase database is down, we need to know that we can switch to the Oracle, but Tomcat will not try and load the Sybase resource from the context.xml at start up (unfortunately I am not in a position to turn off one of the databases to test this! :) ).
From what I can tell, Tomcat is loading the resources - but not trying to actually connect to the database until part of the code invokes the data source, at which point Spring kicks in and does its work. It simply loads in the resources and keeps the info stored somewhere, when Spring tries to create the data source it looks up the corresponding resource info and uses this
Yes, Tomcat will create these datasources at startup. I cannot tell you how far this initialization goes but I would try to avoid any overhead that you dont need.
Do you need both datasources at runtime or is it just to be able to decide at startup of your application?
In the second case you can see the cotext.xml file as an (external) configuration file. You can then use springs jndi reference feature to connect to the desired database for the current application.
In the root-context.xml you reference ONE datasource by name:
<jee:jndi-lookup id="mvcDatasource" jndi-name="jdbc/mvcDatasource"
expected-type="javax.sql.DataSource" />
And depending on which type should be used you declare the correct implementation in the context.xml:
<Context>
<Environment name="configDirectory" type="java.lang.String" value="file:///tmp/app1" />
<Resource name="jdbc/mvcDatasource" type="javax.sql.DataSource" auth="Container" driverClassName="org.h2.Driver" maxActive="8" maxIdle="4" username="user" password="" url="jdbc:h2:file:/tmp/app1/db" />
</Context>
As you can see you can use other declarations too. In my case i inject the external config location here to be able to load properties files for the propertyconfigurer too. So this location will be application specific.
I've set up two tomcat instances running on different ports on the same Windows machine. One is for Alpha, the other is for Development. I've deployed the Alpha and Dev wars (same app name, different settings in META-INF/context.xml) to each server.
The Tomcat directories have the exact same content except for:
Wars deployed are different (I started fresh, removed webapps/* war files and dirs)
conf/server.xml files are different (set different ports)
bin/catalina.bat files are different (changed CATALINA_HOME to the full path of each instance)
The rest is the same.
The thing is that META-INF/context.xml files of each war point to different databases, one for dev and one for alpha. More specifically the connection URL is different, and even more specifically only the database name is different (the string between the slash and the question mark of the URL).
However, after starting both instances for some reason they BOTH point at the Dev database. That is, they both are presumably reading the Dev context.xml, and probably the same webapps/AppName folder
How is that possible?
When I start the Dev tomcat the console displays the values of CATALINA_HOME, CATALINA_BASE, CATALINA_TMPDIR and CLASSPATH, and they all show full paths to the Dev tomcat directory.
When I start the Alpha tomcat the console displays the values of those variables as well, and they all show full paths to the Alpha tomcat directory (so the paths seem to be OK).
I checked the deployed alpha_tomcat_dir/webapps/AppName/META-INF/context.xml file and it DOES show alpha database configuration.
But at runtime it still uses the db information of the Dev database.
Where else should I look?
These are the context.xml files:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/hng"
auth="Container"
driverClassName="com.mysql.jdbc.Driver"
type="javax.sql.DataSource"
maxActive="60"
minIdle="5"
maxIdle="60"
maxWait="10000"
testOnBorrow="true"
testOnReturn="true"
testWhileIdle="true"
validationQuery="SELECT 1"
timeBetweenEvictionRunsMillis="20000"
minEvictableIdleTimeMillis="300000"
removeAbandoned="true"
removeAbandonedTimeout="180"
logAbandoned="true"
username="root"
password="<removed>"
url="jdbc:mysql://127.0.0.1:3306/dbname?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&autoReconnectForPools=true" />
</Context>
The files only differ in the database name. It's "hngdev" for dev and "hngalpha" for alpha (instead of dbname)
If you are 100% sure that the context content is right,
Then I would say check your settings in the database server.
could be that you have created the user wrong in the database server? Given same rights for alpha user and dev user. Maybe you did copy-paste same grant user queries for both?
Also you could try to change db information in alpha context, to some wrong user info/port. Does it still connect?
The problem was that I had a context.xml file equal to the dev environment's in $CATALINA_BASE/conf/[enginename]/[hostname]/[webappname].xml
Due to my server.xml configuration the context descriptor was once copied there before I duplicated the whole tomcat directory structure to make the alpha tomcat environment. And due to my server.xml configuration it was not updated on new deploys of the app. The datasource information was being read from $CATALINA_BASE/conf/[enginename]/[hostname]/[webappname].xml, which I didn't know or expect.
Here's the detailed explanation of how contexts and deployments work on different server configurations:
http://tomcat.apache.org/tomcat-7.0-doc/config/context.html
what is benefit of defining db pool in tomcat vs in spring configuring file
<Resource name="jdbc/DBCPosPool" auth="Container" type="javax.sql.DataSource"
maxActive="30" maxIdle="10" maxWait="10000"
validationQuery="SELECT 1"
testOnBorrow="true"
username="xxx" password="xxx" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://abcd.com/test2?autoReconnect=true"/>
I can think of 3 benefits.
Your datasource can be reused by other web applications
Your datasource can be administered externally, independant from the web application. You never want to re-deploy code if the datasource changes. In big organisations the developer is usually not the person who administers the datasources and stuff.
Environment specific details. It's possible that you're working in a DTAP environments or something similar. The datasource can be different depending on your environment (development, production, ...). You don't want to maintain seperate Spring configuration files just for the sake of the data connection.
Defining pool in tomcat allows you to reuse this definition in others, non spring apps. Defining it in spring level helps you to deploy yor app including other containers.
If your application is packaged to a war file, defining resources in an application server allows you to modify the resources without rebuilding the application. All you need is to restart the application server. This is useful when deploying the same application on different environments (dev, test, prod etc).
I am setting up my JavaEE environment as I have other times in the past. I have always placed the actual password in the DataSource config to access the database. I am wondering if it is prudent/possible/necessary to use a hashed value for the password instead of the actual. Or, is there some other, best practice, way of avoiding use of the actual password?
This may not even be a necessary precaution, but I am curious to know and Googling proved fruitless for me.
Here is how I have set things up in my META-INF --> context.xml in the past (with some settings omitted for simplicity):
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource
name="jdbc/mydatabasename"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://mydburl"
username="myusername"
password="actualpassword"
/>
</Context>
Basically, is there something else I can/should put in place of password="actualpassword" to make things more secure?
I don't think there's a standard way of doing this, but most vendors have implemented something, e.g. JBoss, Jetty or Glassfish.