0

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?

Jane Wayne
  • 8,205
  • 17
  • 75
  • 120

2 Answers2

1

A bcrypt password encryptor, which Spring recommends over SHA or MD5, can be configured like this:

@Bean
public PasswordEncoder passwordEncoder() {
  return new BCryptPasswordEncoder();
}
Sanjay
  • 8,755
  • 7
  • 46
  • 62
0

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);
 }
}
Jane Wayne
  • 8,205
  • 17
  • 75
  • 120
  • 1
    It should also work with the field, i think the Autowired annotation was the problem, since you don't need that, if you have the Value annotation on a field. – dunni Aug 13 '15 at 06:22