Создание пользовательского ресурса Jasypt PropertySource в Springboot

я использую Spring Boot для создания простого веб-приложения, которое обращается к базе данных. Я использую преимущества функции автоконфигурации для источника данных, настроив spring.datasource.* свойства application.properties. Что все работает блестяще и очень быстро - отличная работа ребята @ Spring!

моя политика компании заключается в том, что не должно быть никаких паролей. Поэтому мне нужно иметь sping.datasource.password зашифровать. Немного покопавшись, я решил создать org.springframework.boot.env.PropertySourceLoader реализация, которая создает jasypt org.jasypt.spring31.properties.EncryptablePropertiesPropertySource следующим образом:

public class EncryptedPropertySourceLoader implements PropertySourceLoader
{
    private final StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();

    public EncryptedPropertySourceLoader()
    {
        //TODO: this could be taken from an environment variable
        this.encryptor.setPassword("password"); 
    }

    @Override
    public String[] getFileExtensions()
    {
        return new String[]{"properties"};
    }

    @Override
    public PropertySource<?> load(final String name, final Resource resource, final String profile) throws IOException
    {
        if (profile == null)
        {
            final Properties props = PropertiesLoaderUtils.loadProperties(resource);

            if (!props.isEmpty())
            {
                return new EncryptablePropertiesPropertySource(name, props, this.encryptor);
            }
        }

        return null;
    }
}

затем я упаковал это в собственную банку с следующим образом:

org.springframework.boot.env.PropertySourceLoader=com.mycompany.spring.boot.env.EncryptedPropertySourceLoader

это прекрасно работает при запуске из maven с помощью mvn spring-boot:run. Проблема возникает, когда я запускаю его как автономную войну, используя java -jar my-app.war. Приложение все еще загружается, но терпит неудачу, когда я пытаюсь подключиться к базе данных, поскольку значение пароля все еще зашифровано. Добавление журнала показывает, что EncryptedPropertySourceLoader никогда не загружен.

для меня это звучит как проблема с classpath. При запуске под maven порядок загрузки банки строг, но один раз под embebed tomcat нечего сказать, что моя пользовательская банка должна быть загружена до весенней загрузки.

я попытался добавить следующее К моему pom.xml для обеспечения сохранения classpth, но он, похоже, не имел никакого эффекта.

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <archive>
                        <manifest>
                            <mainClass>${start-class}</mainClass>
                            <addClasspath>true</addClasspath>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

у кого-нибудь есть идеи? Спасибо продвижение.

обновление:

шаг вперед: мне удалось исправить это, имея EncryptedPropertySourceLoader класс реализации org.springframework.core.PriorityOrdered интерфейс и возвращение HIGHEST_PRECEDENCE С getOrder(). Это теперь исправлена проблема PropertySourceLoader не используется. Однако теперь при попытке расшифровать свойства возникает следующая ошибка:

org.jasypt.exceptions.EncryptionInitializationException: java.security.NoSuchAlgorithmException: PBEWithMD5AndDES SecretKeyFactory not available
    at org.jasypt.encryption.pbe.StandardPBEByteEncryptor.initialize(StandardPBEByteEncryptor.java:716)
    at org.jasypt.encryption.pbe.StandardPBEStringEncryptor.initialize(StandardPBEStringEncryptor.java:553)
    at org.jasypt.encryption.pbe.StandardPBEStringEncryptor.decrypt(StandardPBEStringEncryptor.java:705)
    at org.jasypt.properties.PropertyValueEncryptionUtils.decrypt(PropertyValueEncryptionUtils.java:72)
    at org.jasypt.properties.EncryptableProperties.decode(EncryptableProperties.java:230)
    at org.jasypt.properties.EncryptableProperties.get(EncryptableProperties.java:209)
    at org.springframework.core.env.MapPropertySource.getProperty(MapPropertySource.java:36)
    at org.springframework.boot.env.EnumerableCompositePropertySource.getProperty(EnumerableCompositePropertySource.java:49)
    at org.springframework.boot.context.config.ConfigFileApplicationListener$ConfigurationPropertySources.getProperty(ConfigFileApplicationListener.java:490)

снова этого не происходит при запуске из mvn spring-boot:run но случается при запуске из исполняемый файл войны. Оба сценария используют один и тот же JVM (jdk1.6.0_35). Результаты в Google / Stackoverflow предполагают, что это проблема с политикой безопасности java, но поскольку она работает при запуске из maven, я думаю, что могу это дисконтировать. Возможно, проблема с упаковкой...

2 ответов


вы можете попробовать:jasypt-spring-boot Он в основном обертывает все PropertySource, присутствующие в среде с шифруемой версией. 2 вещи, которые вы должны сделать после импорта библиотеки (добавление зависимости, если вы используете maven), - это аннотировать ваш класс @Configuration с помощью @EnableEncryptableProperties и настроить алгоритм шифрования и пароль через свойства.


здесь есть две проблемы.

1) EncryptedPropertySourceLoader должен быть загружен выше, чем стандартный PropertiesPropertySourceLoader. Это может быть достигнуто путем реализации интерфейса PriorityOrder следующим образом:

public class EncryptedPropertySourceLoader implements PropertySourceLoader, PriorityOrdered
{
    private final StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();

    public EncryptedPropertySourceLoader()
    {
        this.encryptor.setPassword("password"); //TODO: this could be taken from an environment variable
    }

    @Override
    public String[] getFileExtensions()
    {
        return new String[]{"properties"};
    }

    @Override
    public PropertySource<?> load(final String name, final Resource resource, final String profile) throws IOException
    {
        if (profile == null)
        {
            //load the properties
            final Properties props = PropertiesLoaderUtils.loadProperties(resource);

            if (!props.isEmpty())
            {
                //create the encryptable properties property source
                return new EncryptablePropertiesPropertySource(name, props, this.encryptor);
            }
        }

        return null;
    }

    @Override
    public int getOrder()
    {
        return HIGHEST_PRECEDENCE;
    }
}

на org.springframework.core.io.support.SpringFactoriesLoader класс, который загружает org.springframework.boot.env.PropertySourceLoader С META-INF/spring.factories заказывает результаты, используя org.springframework.core.OrderComparator. Это означает, что этот класс должен быть возвращен первый и будет возложена ответственность за providinging в PropertySourceLoader реализации *.файлы proerpties.

2) второй-это проблема загрузки класса с исполняемым JAR/WAR, которая, по-видимому, вызвана ошибкой в версии 1.1.2.Выпуск Spring Boot на Windows. Переход к версии 1.1.1.Выпуск или до версии 1.1.3.Выпуск решает различные проблемы с классами и файлами proerpties, которые не загружаются при запуске за пределами maven.