web-dev-qa-db-ja.com

Spring applicationContext.xmlで使用されるデータソースのエンコードされたパスワードの使用

エンコードされたパスワードを下記のspringApplicationContext.xmlに保持したい

これを達成する方法はありますか?

現在、以下に示すようにproperty-placeholderを使用してすべてのプロパティを設定していますが、生のパスワードはまだ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>

実際の値は私のdatabase.propertiesにあります

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

以下のようなものが欲しい:

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>

ただし、パスワードプロパティの値はdatabase.propertiesに暗号化された形式である必要があります

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

私のdataSourceは、新しいDB接続を行う前に内部的にパスワードを復号化します。

これに関するヘルプ/提案を高く評価してください。

21
Sandy

私が自分の質問に答えているのはおかしいかもしれません。しかし、それでも私の解決策、同じ種類の問題に直面した可能性のある他の人たちに伝えたかっただけです。

簡単にするために、BASE64EncoderとBASE64Decoderを使用しました。後で、コードを変更して、安全で優れた暗号化/復号化アルゴリズムを使用します。

以下のコードを使用して、データベースパスワード(例:rootの場合)をエンコードしました。

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

エンコードされたパスワードを次のように私のdatabase.propertiesファイルに配置します。

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

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

これで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;
    }
}

このようにして、database.propertiesで提供されているエンコードされたパスワードをデコード(BASE64Decoder)しています。

また、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>

ありがとう。

19
Sandy

Springを拡張するカスタマイズされたPropertyPlaceHolderConfigurerを作成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
            ...
        }
    }
}

プロパティを暗号化してSomeText:を追加できます。このカスタマイズされたPropertyPlaceHolderConfigurerを使用してプロパティをロードします

9
Sujith

ここで大きな画像を確認したいと思います。プロパティファイルの値を暗号化する理由は何ですか。権限のないユーザーがプロパティファイルにアクセスするシナリオは何ですか?

本番の認証情報を保存するというこのより大きな問題に対処する通常の手法は、認証情報をソースコードの一部ではなく環境の一部にすることです。これを行うには、いくつかの方法があります。

  • プロパティファイル(プレーンテキストパスワード付き)を本番環境のWebサーバーのクラスパスに配置すると、このパスワードへのアクセスは、本番マシンへのアクセスによって制御されます。
  • プロパティをweb.xml(context-param with param-name)に保存します。このファイルも、コードを実行する環境の一部であり、コードとともに配布されません。そのファイルへのアクセスは、マシンへのアクセスによって制御されます。
  • JNDIを使用して、アプリケーションサーバーでそのリソースを設定します。
4
Jay

Datasourceインターフェイスを実装するラッパークラスを作成します。これは、そのメソッド呼び出しを基になるデータソースに委譲しますが、その前にパスワードを復号化します。

3
Abhinav Sarkar

Tomcat接続プールをデータソースとして使用している場合、ここに実装があります

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

Org.Apache.Tomcat.jdbc.pool.DataSourceFactoryを拡張するクラスを作成し、server.xmlで構成します

0
Sujith Nair