web-dev-qa-db-fra.com

Utilisation d'un mot de passe codé pour la source de données utilisée dans spring applicationContext.xml

Je souhaite conserver le mot de passe codé dans le fichier springApplicationContext.xml mentionné ci-dessous.

Y'a-t-il une quelconque façon de réussir cela? 

actuellement, j'ai configuré toutes les propriétés à l'aide de property-placeholderas ci-dessous, mais le mot de passe brut est toujours ouvert dans mon 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>

mais les valeurs réelles sont présentes dans mon database.properties

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

Je veux quelque chose comme ci-dessous:

springApplicationContext.xml (comme ci-dessus)

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

Mais la valeur de la propriété de mot de passe doit être au format énoncé dans mon database.properties

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

et mon source de données déchiffre en interne le mot de passe avant d'établir une nouvelle connexion à la base de données.

Très apprécié pour toute aide/suggestion dans ce domaine.

21
Sandy

C'est peut-être drôle que je réponde à ma propre question. mais je voulais juste dire ma solution, d’autres qui auraient pu faire face au même genre de problème ..

pour plus de simplicité, j'ai utilisé BASE64Encoder & BASE64Decoder. plus tard, je modifierai mon code pour utiliser un algorithme de cryptage/décryptage sécurisé/amélioré.

J'ai encodé mon mot de passe de base de données (ex: root pour mon cas) en utilisant le code ci-dessous:

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

et placé le mot de passe codé dans mon fichier database.properties comme ci-dessous:

avant

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

après

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

Maintenant, j'ai écrit une classe wrapper pour org.Apache.commons.dbcp.BasicDataSource Et la méthode setPassword () remplacée:

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;
    }
}

De cette façon, je décode (BASE64Decoder) le mot de passe codé fourni dans database.properties

et également modifié l'attribut de classe de mon bean dataSource mentionné dans le fichier springApplicationContext.xml.

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

Merci.

19
Sandy

Créez un PropertyPlaceHolderConfigurer personnalisé prolongeant 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
            ...
        }
    }
}

Vous pouvez chiffrer les propriétés et ajouter SomeText: . Utilisez ce PropertyPlaceHolderConfigurer personnalisé pour charger les propriétés.

9
Sujith

Je voudrais regarder l'image plus grande ici: pourquoi voulez-vous chiffrer des valeurs dans votre fichier de propriétés? Quel est votre scénario où des personnes non autorisées ont accès à votre fichier de propriétés? 

Une technique habituelle pour traiter ce problème plus important de stockage des informations d'identification de production consiste à intégrer les informations d'identification à votre environnement plutôt qu'à votre code source. Voici quelques façons de le faire:

  • Placer le fichier de propriétés (avec les mots de passe en clair) sur le chemin de classe du serveur Web en production, de cette manière, l'accès à ce mot de passe est contrôlé par l'accès à la machine de production.
  • Stockez les propriétés dans web.xml (context-param avec nom-paramètre). Ce fichier fait également partie de l'environnement dans lequel vous exécutez votre code et n'est pas distribué avec votre code. L'accès à ce fichier est contrôlé par l'accès à la machine.
  • Utilisez JNDI et configurez cette ressource sur votre serveur d'applications.
3
Jay

Créez une classe wrapper implémentant l'interface Datasource qui délègue ses appels de méthode à la source de données sous-jacente mais déchiffre le mot de passe avant de le faire.

3
Abhinav Sarkar

Si vous utilisez le pool de connexions Tomcat comme source de données, voici une implémentation. 

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

Créez une classe qui étend org.Apache.Tomcat.jdbc.pool.DataSourceFactory et configurez-la dans le fichier server.xml. 

0
Sujith Nair