Domanda

I want to keep encoded password in my below mentioned springApplicationContext.xml

Is there any way to achieve this?

presently I have configured all properties using property-placeholder as shown below but the raw password is still open in my database.properties

springApplicationContext.xml

<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <beans:property name="driverClassName"><beans:value>${db.driverClassName}</beans:value></beans:property>
        <beans:property name="url"><beans:value>${db.url}</beans:value></beans:property>
        <beans:property name="username"><beans:value>${db.username}</beans:value></beans:property>
        <beans:property name="password"><beans:value>${db.password}</beans:value></beans:property>
</beans:bean>

but actual values are present in my database.properties

db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost/myDB
db.username=root
db.password=root

I want something like below:

springApplicationContext.xml (same as above)

<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <beans:property name="driverClassName"><beans:value>${db.driverClassName}</beans:value></beans:property>
        <beans:property name="url"><beans:value>${db.url}</beans:value></beans:property>
        <beans:property name="username"><beans:value>${db.username}</beans:value></beans:property>
        <beans:property name="password"><beans:value>${db.password}</beans:value></beans:property>
</beans:bean>

But password property value should be in encripted format in my database.properties

db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost/myDB
db.username=root
db.password=3g6n72ef8x (using any encription method).

and my dataSource internally decrypt the password before making new DB connection.

Highly appreciate for any help/suggestion in this.

È stato utile?

Soluzione

Its might be funny that I am answering to my own question. but still I just wanted to tell my solution, others who might have faced same kind of issue..

for simplicity I have used BASE64Encoder & BASE64Decoder. later I will modify my code to use a secure/better encryption/decryption algorithm.

I have encoded my database password(ex: root for my case) by using the below code:

private String encode(String str) {
        BASE64Encoder encoder = new BASE64Encoder();
        str = new String(encoder.encodeBuffer(str.getBytes()));
        return str;
    }

and placed the encoded password in my database.properties file like below:

before

db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost/myDB
db.username=root
db.password=root

after

db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost/myDB
db.username=root
db.password=cm9vdA==  (Note: encoded 'root' by using BASE64Encoder)

Now I have written a wrapper class for org.apache.commons.dbcp.BasicDataSource and overridden setPassword() method:

import java.io.IOException;
import org.apache.commons.dbcp.BasicDataSource;
import sun.misc.BASE64Decoder;

public class MyCustomBasicDataSource extends BasicDataSource{

    public CustomBasicDataSource() {
        super();
    }

    public synchronized void setPassword(String encodedPassword){
        this.password = decode(encodedPassword);
    }

    private String decode(String password) {
        BASE64Decoder decoder = new BASE64Decoder();
        String decodedPassword = null;
        try {
            decodedPassword = new String(decoder.decodeBuffer(password));
        } catch (IOException e) {
            e.printStackTrace();
        }       
        return decodedPassword;
    }
}

This way I am decoding(BASE64Decoder) the encoded password provided in database.properties

and also modified the class attribute of my dataSource bean mentioned in springApplicationContext.xml file.

<beans:bean id="dataSource" class="edu.config.db.datasource.custom.MyCustomBasicDataSource" destroy-method="close">
    <beans:property name="driverClassName"><beans:value>${db.driverClassName}</beans:value></beans:property>
    <beans:property name="url"><beans:value>${db.url}</beans:value></beans:property>
    <beans:property name="username"><beans:value>${db.username}</beans:value></beans:property>
    <beans:property name="password"><beans:value>${db.password}</beans:value></beans:property>

Thanks.

Altri suggerimenti

Create customized PropertyPlaceHolderConfigurer extending Spring PropertyPlaceHolderConfigurer

public class PropertyPlaceholderConfigurer extends
        org.springframework.beans.factory.config.PropertyPlaceholderConfigurer {

    @Override
    protected String convertPropertyValue(final String originalValue) {
        if (originalValue.startwith("SomeText:")) {
            //Apply the decryption logic
            ...
        }
    }
}

You can encrypt the properties and append SomeText:. Use this customized PropertyPlaceHolderConfigurer to load the properties

I'd like to look at the larger picture here: why do you want to encrypt values in your properties file? What is your scenario where unauthorized people have access to your properties file?

A usual technique to deal with this larger problem of storing production credentials is to make credentials a part of your environment as opposed to part of your source code. Here are some ways to do this:

  • Placing the properties file (with plaintext passwords) on the classpath of the web server in production, this way access to that password is controlled by access to the production machine.
  • Store properties in web.xml (context-param with param-name), again this file is part of the environment in which you run your code and not distributed with your code - access to that file is controlled by access to the machine.
  • Use JNDI and configure that resource in your application server.

Create a wrapper class implementing the Datasource interface which delegates it's method calls to the underlying datasource but decrypts the password before doing so.

If you are using tomcat connection pool as data source, here is an implementation

http://www.jdev.it/encrypting-passwords-in-tomcat/

Create a class which extends org.apache.tomcat.jdbc.pool.DataSourceFactory and configure it in the server.xml

Update:

The newer way is to use Jasypt: http://www.jasypt.org/encrypting-texts.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top