在应用程序之间共享 Spring Security 配置
-
13-09-2019 - |
题
我是 Spring 的新手,我从 Apress 的 Spring Recipes 书中获得了大部分知识。
我已经在一个 Web 应用程序中使用 Spring Security 进行 LDAP 身份验证。然而,我想从这个 web 应用程序中删除我的应用程序上下文 bean 和属性文件,并以某种方式将它们外部化,以便我们所有的 web 应用程序都可以引用相同的 bean。因此,当我们需要更改某些内容(例如 ldapuser 或 ldap url)时,我们会在一处更改它,其余应用程序就会知道。
更新我已经实施了 可重载弹簧属性 当属性来自的文件被触摸时,它会重新加载属性。然而,我使用的是加密属性,因此下面是我在可重新加载 Spring 属性之上创建的类。
重新加载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));
}
}
这是我在我的应用程序中使用它的方法 安全上下文.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>
解决方案
怎么样:
- 编写返回列表的方法 LDAP 服务器 - 从 数据库表或属性文件
- 通过 jndi 公开此方法,并使用它将服务器列表注入到您的 spring 配置中
- 如果您需要动态刷新 ldap 服务器,您可以定期对更改进行作业轮询,或者使用管理网页或 jmx bean 来触发更新。请注意这两种方法的并发问题(在更新时读取列表)
其他提示
那不是春季安全?它可以处理的LDAP。如果你让一个安全服务,每个人都使用,那不是管理的方式?
不隶属于 StackOverflow