2009-07-15 117 views
0

我是Spring的新品牌,已经从Apress的Spring Recipes书中获得了大部分知识。在应用程序之间共享弹簧安全配置

我在一个webapp中使用了Spring Security的LDAP身份验证。然而,我想从这个webapp中剔除我的应用程序上下文bean和属性文件,并以某种方式将它们外部化,以便我们所有的webapps都可以引用相同的bean。所以当我们需要改变某些东西时(比如ldapuser或ldap网址),我们在一个地方改变它,其余的应用程序只知道。

UPDATE 我实施了Reloadable Spring Properties,当它们来自的文件被触及时,它正在重新加载属性。我使用加密属性,但是,下面是我在Reloadable Spring Properties之上创建的类。

ReloadingEncryptablePropertyPlaceholderConfigurer.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> 
+0

您是指在运行时共享,还是在构建时共享? – skaffman 2009-07-15 07:37:32

+0

运行时间。我希望能够全局更改ldap上下文,而无需在每个部署的应用程序的上下文中更改它。 – 2009-07-15 14:09:42

回答

1

如何:

  • 编写返回LDAP服务器的列表 的方法 - 从 数据库表或属性文件中读取
  • 通过JNDI使本wethod并用它来注入的列表将服务器放入您的弹性配置
  • 如果您需要动态刷新ldap服务器,您可以定期进行作业轮询更改,或者使用管理网页或jmx bean触发更新。请注意这两种方法的并发性(在您更新时读取列表的内容)
0

那不是春季安全?它可以处理LDAP。如果你让它成为每个人都使用的安全服务,那不是管理它的方法吗?

+0

我们已经在Spring Security中设置了它。所有的LDAP服务器现在都在一个applicationContext文件中,这就是我想要从外部源获取的内容。如果我必须为每个应用维护一个ldap服务器列表,那将会非常可怕。 – 2009-07-15 02:50:50