Совместное использование конфигурации безопасности Spring между приложениями

Я новичок в Spring и получил большую часть знаний, которые у меня есть, из книги Spring Recipes от Apress.

У меня есть аутентификация LDAP, работающая с Spring Security в одном веб-приложении. Однако я хотел бы вырвать компоненты контекста приложения и файлы свойств из этого одного веб-приложения и каким-то образом вынести их наружу, чтобы все наши веб-приложения могли ссылаться на одни и те же компоненты. Поэтому, когда нам нужно что-то изменить (например, ldapuser или URL-адреса ldap), мы меняем это в одном месте, а остальные приложения просто знают об этом.

ОБНОВЛЕНИЕ Я реализовал Reloadable Spring Properties, который перезагружается свойства при прикосновении к файлам, из которых они исходят. Однако я использую зашифрованные свойства, поэтому ниже приведен класс, который я создал поверх Reloadable Spring Properties.

ПерезагрузкаEncryptablePropertyPlaceholderConfigurer.java

package;

import java.util.Properties;
import java.util.Set;

import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.jasypt.encryption.StringEncryptor;
import org.jasypt.util.text.TextEncryptor;
import org.jasypt.properties.PropertyValueEncryptionUtils;

import org.springframework.beans.factory.BeanDefinitionStoreException;

public class ReloadingEncryptablePropertyPlaceholderConfigurer extends ReloadingPropertyPlaceholderConfigurer {

    protected final Log logger = LogFactory.getLog(getClass());
    private final StringEncryptor stringEncryptor;
    private final TextEncryptor textEncryptor;

    public ReloadingEncryptablePropertyPlaceholderConfigurer(TextEncryptor textEncryptor) {
        super();
        logger.info("Creating configurer with TextEncryptor");
        Validate.notNull(textEncryptor, "Encryptor cannot be null");
        this.stringEncryptor = null;
        this.textEncryptor = textEncryptor;
    }

    public ReloadingEncryptablePropertyPlaceholderConfigurer(StringEncryptor stringEncryptor) {
        super();
        logger.info("Creating configurer with StringEncryptor");
        Validate.notNull(stringEncryptor, "Encryptor cannot be null");
        this.stringEncryptor = stringEncryptor;
        this.textEncryptor = null;
    }

    @Override
    protected String convertPropertyValue(String originalValue) {
        if (!PropertyValueEncryptionUtils.isEncryptedValue(originalValue)) {
            return originalValue;
        }
        if (this.stringEncryptor != null) {
            return PropertyValueEncryptionUtils.decrypt(originalValue, this.stringEncryptor);
        }
        return PropertyValueEncryptionUtils.decrypt(originalValue, this.textEncryptor);
    }

    @Override
    protected String parseStringValue(String strVal, Properties props, Set visitedPlaceholders) throws BeanDefinitionStoreException {
        return convertPropertyValue(super.parseStringValue(strVal, props, visitedPlaceholders));
    }
}

А вот как я использую его в своем securityContext.xml:

<bean id="securityContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
    <constructor-arg value="ldaps://ldapserver" />
    <property name="urls" value="#{ldap.urls}" />
</bean>

<bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean">
    <property name="scheduledTimerTasks">
        <bean id="reloadProperties" class="org.springframework.scheduling.timer.ScheduledTimerTask">
            <property name="period" value="1000"/>
            <property name="runnable">
                <bean class="ReloadConfiguration">
                    <property name="reconfigurableBeans">
                        <list>
                            <ref bean="configproperties"/>
                        </list>
                    </property>
                </bean>
            </property>
        </bean>
    </property>
</bean>

<bean id="configproperties" class="ReloadablePropertiesFactoryBean">
    <property name="location" value="classpath:ldap.properties"/>
</bean>

<bean id="ldapPropertyConfigurer" class="ReloadingEncryptablePropertyPlaceholderConfigurer">
    <constructor-arg ref="configurationEncryptor" />
    <property name="ignoreUnresolvablePlaceholders" value="true" />
    <property name="properties" ref="configproperties"/>
</bean>

<bean id="jasyptConfig" class="org.jasypt.encryption.pbe.config.SimpleStringPBEConfig">
    <property name="algorithm" value="PBEWithMD5AndTripleDES" />
    <property name="password" value="########" />
</bean>

<bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
    <property name="config" ref="jasyptConfig" />
</bean>

person Buns of Aluminum    schedule 15.07.2009    source источник
comment
Вы имеете в виду общий доступ во время выполнения или общий доступ во время сборки?   -  person skaffman    schedule 15.07.2009
comment
Время выполнения. Я хочу иметь возможность глобально изменить контекст ldap без необходимости изменять его в контексте каждого развернутого приложения.   -  person Buns of Aluminum    schedule 15.07.2009


Ответы (2)


Как насчет:

  • Написание метода, который возвращает список серверов LDAP — чтение из таблицы базы данных или файлов свойств
  • разоблачите этот метод через jndi и используйте его для ввода списка серверов в вашу конфигурацию spring.
  • Если вам нужно, чтобы серверы ldap обновлялись динамически, вы можете периодически проводить опрос на предмет изменений или иметь веб-страницу администратора или компонент jmx для запуска обновления. Будьте осторожны с параллелизмом для обоих этих методов (что-то читает список во время обновления)
person Pablojim    schedule 15.07.2009
comment
Благодарю за ваш ответ! Это звучит как интересное решение, но я не думаю, что у меня достаточно опыта работы со Spring, чтобы понять, как его реализовать. Не могли бы вы привести пример, связанный с экспозицией jndi и инжекцией пружины? Будет ли Spring обрабатывать опрос? - person Buns of Aluminum; 22.07.2009
comment
По сути, это то, что я сделал, хотя и по-другому. Я написал, что я сделал в обновлении проблемы. - person Buns of Aluminum; 27.07.2009

Разве это не Spring Security? Он может работать с LDAP. И если вы сделаете его единым сервисом безопасности, которым пользуются все, разве это не будет способом управления им?

person duffymo    schedule 15.07.2009
comment
Мы настроили его в Spring Security. Все серверы LDAP прямо сейчас находятся в файле applicationContext, и это то, что я хочу получить из внешнего источника. Если бы мне пришлось вести список серверов ldap для каждого приложения, это было бы ужасно. - person Buns of Aluminum; 15.07.2009