2009-07-15 16 views
0

Ich bin brandneu im Frühjahr und habe einen Großteil des Wissens, das ich aus dem Frühling Rezepte Buch von Apress habe.Frühling Sicherheitskonfiguration zwischen Anwendungen teilen

Ich habe LDAP-Authentifizierung mit Spring Security in einer Webanwendung arbeiten. Ich möchte jedoch meine Anwendungskontext-Beans und Eigenschaftendateien aus dieser einen Webanwendung herausreißen und sie irgendwie externalisieren, so dass alle unsere Webapps dieselben Beans referenzieren können. Wenn wir also etwas ändern müssen (wie die ldapuser- oder ldap-URLs), ändern wir es an einer Stelle und der Rest der Apps weiß es einfach.

UPDATE Ich habe Reloadable Spring Properties implementiert, die Eigenschaften Nachladen, wenn die Dateien sie kommen berührt werden. Ich verwende jedoch verschlüsselte Eigenschaften, daher ist unten die Klasse, die ich über die Eigenschaften von Reloadable Spring Properties erstellt habe.

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

Und hier ist, wie ich es in meinem securityContext.xml verwenden:

<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

Meinen Sie zur Laufzeit freigegeben oder zur Build-Zeit geteilt? – skaffman

+0

Laufzeit. Ich möchte in der Lage sein, den LDAP-Kontext global zu ändern, ohne ihn in jedem Kontext der bereitgestellten Anwendung ändern zu müssen. –

Antwort

1

Wie wäre:

  • ein Verfahren zu schreiben, die von LDAP-Server eine Liste zurückgibt - aus einer Dateien Datenbanktabelle oder Eigenschaft lesen
  • dieses wethod über jndi aussetzen und es verwenden, um eine Liste von injizieren Die Server in Ihre Spring-Konfiguration
  • Wenn Sie die LDAP-Server dynamisch aktualisiert werden müssen, können Sie regelmäßig eine Jobabstimmung für Änderungen durchführen oder eine Admin-Webseite oder eine Jmx-Bean zum Auslösen des Updates haben. Seien Sie vorsichtig bei Gleichzeitigkeits-Isses für diese beiden Methoden (etwas, das die Liste während der Aktualisierung liest)
+0

Vielen Dank für Ihre Antwort! Das hört sich nach einer interessanten Lösung an, aber ich denke nicht, dass ich genug Erfahrung mit Spring habe, um herauszufinden, wie man es implementiert. Könnten Sie mir ein Beispiel geben, das die Jndi-Belichtung und die Frühlingseinspritzung beinhaltet? Würde Spring die Abstimmung übernehmen? –

+0

Dies ist im Wesentlichen was ich getan habe, obwohl anders. Ich habe gepostet, was ich bei der Aktualisierung des Problems getan habe. –

0

Wäre das nicht Spring Security sein? Es kann mit LDAPs umgehen. Und wenn Sie es zu einem Sicherheitsdienst machen, den jeder nutzt, wäre das nicht der richtige Weg?

+0

Wir haben es in Spring Security eingerichtet. Alle LDAP-Server befinden sich gerade in einer applicationContext-Datei, und das möchte ich von einer externen Quelle beziehen können. Wenn ich für jede App eine Liste von LDAP-Servern verwalten müsste, würde das schrecklich werden. –

Verwandte Themen