Question

L'objectif est de traiter les mots de passe obfusqués pour les ressources.

Nous avons un conseiller qui intercepte les appels à setPassword et déchiffre l'argument.

Nous avons mis en place un modèle ressemblant un peu à ceci:

<bean id="pwAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
   <property name="advice"><bean class="our.advice.bean.class"/></property>
   <property name="mappedName" value="setPassword"/>
</bean>
<bean id="passwordHandlerTemplate" class="org.springframework.aop.framework.ProxyFactoryBean" abstract="true">
   <property name="interceptorNames"><list><value>pwAdvisor</value></list></property>
</bean>

Je ne suis pas sûr de la syntaxe exacte à utiliser. Le moyen le plus évident est:

<bean id="myPasswordProtectedThing" parent="passwordHandlerTemplate">
   <property name="target">
      <bean class="the.target.class.name">
         <property name="password" value="encrypted garbage"/>
      </bean>
    </property>
 </bean>

Mais cela ne fonctionne pas correctement, car la propriété password est appliquée au bean interne, ce qui signifie que le conseiller ne finira pas par faire son travail.

Eh bien, qu'en est-il de cela:

<bean id="myPasswordProtectedThing" parent="passwordHandlerTemplate">
   <property name="target"><bean class="the.target.class.name"/></property>
   <property name="password" value="encrypted garbage"/>
</bean>

Nope. Spring se plaint que ProxyFactoryBean ne possède pas de propriété de mot de passe. Et bien sûr, ce n'est pas le cas. Ce qui a la propriété password est ce que le bean factory crée .

Bueller?

Était-ce utile?

La solution

Mon premier effort a été médiocre, mais j'étais pressé. Je m'excuse. Maintenant, je pense savoir comment cela devrait fonctionner, car je crois avoir mis en œuvre ce que vous voulez moi-même.

J'ai commencé avec une classe Credential (note: pas d'interface):


package aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Credential
{
   private static final String DEFAULT_USERNAME = "username";
   private static final String DEFAULT_PASSWORD = "password";

   private String username;
   private String password;

   public static void main(String[] args)
   {
      Credential cred1 = new Credential("foo", "bar");
      System.out.println("created using new: " + cred1);

      ApplicationContext context = new ClassPathXmlApplicationContext("classpath:aop-context.xml");
      Credential cred2 = (Credential) context.getBean("credential");

      System.out.println("created using app context: " + cred2);

      String password = ((args.length > 0) ? args[0] : "baz");
      cred2.setPassword(password);

      System.out.println("initialized using setter: " + cred2);      
   }

   public Credential()
   {
      this(DEFAULT_USERNAME, DEFAULT_PASSWORD);
   }

   public Credential(String username, String password)
   {
      this.setUsername(username);
      this.setPassword(password);
   }

   public String getUsername()
   {
      return username;
   }

   public void setUsername(String username)
   {
      this.username = username;
   }

   public String getPassword()
   {
      return password;
   }

   public void setPassword(String password)
   {
      this.password = password;
   }


   public String toString()
   {
      return new StringBuilder().append("Credential{").append("username='").append(username).append('\'').append(", password='").append(password).append('\'').append('}').toString();
   }
}

J'ai créé une interface Decryptor:


package aop;

public interface Decryptor
{
   String decrypt(String encrypted);
}

Et un DecryptorImpl:


package aop;

public class DecryptorImpl implements Decryptor
{
   public static final String DEFAULT_DECRYPTED_VALUE = " - not secret anymore";

   public String decrypt(String encrypted)
   {
      // Any transform will do; this suffices to demonstrate
      return encrypted + DEFAULT_DECRYPTED_VALUE;
   }
}


J'avais besoin de DecryptorAdvice pour implémenter le MethodBeforeAdvice de Spring:



package aop;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class DecryptionAdvice implements MethodBeforeAdvice
{
   private Decryptor decryptor;


   public DecryptionAdvice(Decryptor decryptor)
   {
      this.decryptor = decryptor;
   }

   public void before(Method method, Object[] args, Object target) throws Throwable
   {
      String encryptedPassword = (String) args[0];

      args[0] = this.decryptor.decrypt(encryptedPassword);
   }
}

Et je l'ai câblé ensemble dans un fichier aop-context.xml. (Si vous me dites comment afficher XML, je le posterai.) Notez le mot de passe passwordDecryptionAdvisor: il ne correspond qu'à la méthode setPassword.

La partie intéressante se produit lorsque je l’exécute. Voici ce que je vois dans la console:


created using new: Credential{username='foo', password='bar'}
created using app context: Credential{username='stackoverflow', password='encrypted-password'}
initialized using setter: Credential{username='stackoverflow', password='baz - not secret anymore'}

Cela me dit ceci:

  1. Si je crée un objet avec un nouveau c'est pas sous le contrôle de Spring, conseil n'est pas appliqué.
  2. Si j'appelle setPassword dans le ctor avant que le contexte de l'application ne soit initialisé, les conseils ne sont pas appliqués.
  3. Si j'appelle setPassword dans mon code après le contexte de l'application est initialisé, le conseil est appliqué.

J'espère que cela pourra vous aider.

Autres conseils

Je pensais que vous souhaitiez que le conseil beforeMethod utilise le mot de passe chiffré. Chaîne transmise à la méthode setPassword. Vous souhaitez le déchiffrer et demander à la classe conseillée d'obtenir une version déchiffrée.

Je ne vois pas non plus d’interface proxy définie dans votre fabrique de proxy. "Spring In Action" dit "... La création d'un proxy avec des interfaces est privilégiée par rapport aux classes de proxy ..." Les classes de proxy doivent être l'exception et non la règle.

Publiez votre classe de conseils.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top