문제

여기서 의도는 리소스에 대한 난독 화 된 암호를 다루는 것입니다.

우리는 setpassword에 대한 호출을 가로 채고 논증을 암호화하는 고문이 있습니다.

우리는 다음과 같은 것처럼 보이는 템플릿을 설정했습니다.

<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>

나는 그것을 사용하기 위해 정확한 구문이 불분명합니다. 가장 분명한 방법은 다음과 같습니다.

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

그러나 비밀번호 속성이 내부 콩에 적용되므로 고문이 작업을 수행하지 않기 때문에 제대로 작동하지 않습니다.

글쎄, 이것은 어떻습니까 :

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

아니요. Spring은 proxyFactoryBean에 암호 속성이 없다고 불평합니다. 물론 그렇지 않습니다. 암호 속성이있는 것은 공장 Bean입니다. 생성.

버셀?

도움이 되었습니까?

해결책

나의 첫 번째 노력은 가난했지만 나는 서둘러 있었다. 사과드립니다. 이제 나는 그것이 어떻게 작동 해야하는지 알고 있다고 생각합니다. 왜냐하면 나는 당신이 원하는 것을 구현했다고 생각하기 때문입니다.

자격 증명 수업으로 시작했습니다 (참고 : 인터페이스 없음) :


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

해독자 인터페이스를 만들었습니다.


package aop;

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

그리고 해독자 :


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


Spring의 MethodbeForeadVice를 구현하기 위해 DecryptorAdvice가 필요했습니다.



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

그리고 나는 그것을 AOP-Context.xml로 함께 연결했습니다. (XML을 표시하는 방법을 알려 주시면 게시하겠습니다.) PasswordDecryptionAdvisor에 주목하십시오. SetPassword 메소드 만 일치합니다.

흥미로운 부분은 내가 실행할 때 발생합니다. 콘솔에서 볼 수있는 것은 다음과 같습니다.


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'}

이것이 나에게 말하는 것은 다음과 같습니다.

  1. 새로운 객체를 만들면 Spring의 통제하에 있지 않으면 조언이 적용되지 않습니다.
  2. 앱 컨텍스트가 초기화되기 전에 CTOR에서 SetPassword를 호출하면 조언이 적용되지 않습니다.
  3. 앱 컨텍스트가 초기화 된 후 코드에서 setpassword를 호출하면 조언이 적용됩니다.

이것이 당신을 도울 수 있기를 바랍니다.

다른 팁

나는 당신이 setpassword 메소드에 전달되는 암호화 된 암호 문자열을 사용하기 위해 Beforemethod 조언을 원한다고 생각했습니다. 이를 해독하고 조언 클래스에 해독 된 버전을 얻도록하려고합니다.

또한 프록시 공장에 프록시 인터페이스가 설정되어 있지 않습니다. "Spring In Action"은 "... 인터페이스로 프록시를 만드는 것이 프록시 클래스보다 선호됩니다 ..."프록시 클래스는 규칙이 아닌 예외가되어야합니다.

조언 수업을 게시하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top