Search code examples
javaspringspring-bootspring-annotations

How do I define a PasswordEncoder using annotations in Spring?


I am using Spring-Boot v1.3.0.M2. I am trying to define a o.s.s.c.p.PasswordEncoder using annotations. My configuration class looks like the following. This example works fine.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 @Bean
 public PasswordEncoder getPasswordEncoder() { 
  return new StandardPasswordEncoder();
 }
}

However, I would like to instantiate the StandardPasswordEncoder with a secret, and I've revised my class as follows.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

 @Autowired
 @Value(value="${password.secret}")
 private String secret;

 @Bean
 public PasswordEncoder getPasswordEncoder() { 
  return new StandardPasswordEncoder(secret);
 }
}

Please note my Spring-Boot application looks like the following.

@SpringBootApplication
@PropertySource("classpath:/config/myapp.properties")
public class Application {
 public static void main(String[] args) {
  SpringApplications.run(Application.class, args);
 }

 @Bean
 public static PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholdConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
 }
}

And my myapp.properties looks like the following.

password.secret=fsdkjfsldfsdfsdfsdf

When I try to run my Spring-Boot application, I get the following exception.


Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.crypto.password.PasswordEncoder]: Circular reference involving containing bean 'webSecurityConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'getPasswordEncoder' threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    ... 102 more

The PasswordEncoder couldn't be instantiated because the field private String secret; is not set, and thus the NullPointerException (NPE). I tried making the method getPasswordEncoder static as well as the field secret, but that doesn't help.

Any ideas on how I can use annotations to get an instance of PasswordEncoder with a secret?


Solution

  • I found the answer by tinkering a bit. I removed the field secret and simply annotated the parameter with the method instead as follows.

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
     @Bean
     public PasswordEncoder getPasswordEncoder(@Value(value="${password.secret}") String secret) { 
      return new StandardPasswordEncoder(secret);
     }
    }