对 spring applicationContext.xml 中使用的数据源使用编码密码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12834604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 05:25:18  来源:igfitidea点击:

Using encoded password for the datasource used in spring applicationContext.xml

springhibernatedatasourceapache-commons-dbcppassword-encryption

提问by Sandy

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

我想在下面提到的 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

目前我已经使用 property-placeholder 配置了所有属性,如下所示,但原始密码仍然在我的 database.properties 中打开

springApplicationContext.xml

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

但实际值存在于我的 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)

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 password property value should be in encripted format in my database.properties

但是密码属性值应该是我的加密格式 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.

非常感谢您对此的任何帮助/建议。

采纳答案by Sandy

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.

为简单起见,我使用了 BASE64Encoder 和 BASE64Decoder。稍后我将修改我的代码以使用安全/更好的加密/解密算法。

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

我使用以下代码编码了我的数据库密码(例如:root 对于我的情况):

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:

并将编码后的密码放在我的 database.properties 文件中,如下所示:

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:

现在我已经为 org.apache.commons.dbcp.BasicDataSource 和重写的 setPassword() 方法编写了一个包装类:

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

这样我解码(BASE64Decoder)database.properties中提供的编码密码

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

并且还修改了 springApplicationContext.xml 文件中提到的我的 dataSource bean 的 class 属性。

<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.

谢谢。

回答by Sujith

Create customized PropertyPlaceHolderConfigurer extending Spring PropertyPlaceHolderConfigurer

创建自定义的 PropertyPlaceHolderConfigurer 扩展 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

您可以加密属性并附加SomeText:。使用这个定制的 PropertyPlaceHolderConfigurer 加载属性

回答by Jay

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.
  • 将属性文件(带有明文密码)放在生产中 Web 服务器的类路径上,这样对密码的访问由对生产机器的访问控制。
  • 将属性存储在 web.xml(带有 param-name 的上下文参数)中,同样,此文件是您运行代码的环境的一部分,而不是随代码一起分发 - 对该文件的访问由对机器的访问控制。
  • 使用 JNDI 并在您的应用程序服务器中配置该资源。

回答by Abhinav Sarkar

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

创建一个实现Datasource接口的包装类,该接口将其方法调用委托给底层数据源,但在这样做之前解密密码。

回答by Sujith Nair

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

如果你使用tomcat连接池作为数据源,这里有一个实现

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

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

创建一个扩展 org.apache.tomcat.jdbc.pool.DataSourceFactory 的类并在 server.xml 中配置它