I am using BCryptPasswordEncoder to encode my password but when i use its encode function to encode the password in my save function in UserService class it gives me this error:
Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'userServiceInter'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'crypt'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
When i remove this it works but the password is not encoded.
UserService class:
@Service
public class UserService implements UserServiceInterface{
@Autowired
UserRepository repo;
@Autowired
BCryptPasswordEncoder crypt;
@Autowired
RoleRepository roleRepo;
public void save(User user) {
user.setPassword(crypt.encode(user.getPassword()));
Role role = roleRepo.findByRole("USER");
user.setRoles(new HashSet<Role>(Arrays.asList(role)));
repo.save(user);
}
@Override
public User findByUsername(String userName) {
User user = repo.findByUserName(userName);
return user;
}
}
UserServiceInterface:
@Service
public interface UserServiceInterface {
public void save(User user);
public User findByUsername(String userName);
}
SecurityConfiguration:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends
WebSecurityConfigurerAdapter {
@Autowired
UserPrincipleDetailsService user;
@Autowired
private SimpleAuthenticationSuccessHandler successHandler;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws
Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/assets/css/**").permitAll()
.antMatchers("/img/**").permitAll()
.antMatchers("/home").permitAll()
.antMatchers("/register/**").permitAll()
.antMatchers("/registerUser").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("ADMIN","USER")
.anyRequest().authenticated()
.and()
.csrf().disable()
.formLogin()
.successHandler(successHandler)
.loginPage("/home").permitAll()
.loginProcessingUrl("/signin")
.failureUrl("/home?error=true")
.and()
.logout().logoutRequestMatcher(new
AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/home")
.and()
.exceptionHandling().accessDeniedPage("/home");
}
@Bean
DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider dao = new
DaoAuthenticationProvider();
dao.setPasswordEncoder(passwordEncoder());
dao.setUserDetailsService(user);
return dao;
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
change
@Autowired
BCryptPasswordEncoder crypt;
to
@Autowired
PasswordEncoder crypt
or change passwordEncoder method
@Bean
BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
I agree Shailesh answer is 100% acceptable. If you wants to know
From below code
@Bean
PasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
Definitely bean is created with the name passwordEncoder
of type PasswordEncoder
.
But
@Autowired
BCryptPasswordEncoder crypt;
Above code asking spring container to inject a bean of type BCryptPasswordEncoder
.
(Note: passwordEncoder bean may be instance of BCryptPasswordEncoder but bean is of type PasswordEncoder
and hence there is no bean of type BCryptPasswordEncoder
)
Hence exception
No qualifying bean of type 'org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' available
passwordEncoder
to a field of type PasswordEncoder
.@Autowired
PasswordEncoder crypt;
passwordEncoder
from application context @Autowired
ApplicationContext context;
inYourMethod()
{
PasswordEncoder crypt = context.getBean("passwordEncoder");
}
@Bean
, @Autowired
and @Qualifier
Simple 6 cases that explains very wellCase 1: Created bean type and Autowired field's type are Different - [This Will not work]
(No qualifying bean of type BCryptPasswordEncoder available)
@Autowired
BCryptPasswordEncoder passwordEncoder;
@Bean
PasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
@Autowired
PasswordEncoder passwordEncoder;
@Bean
PasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
@Autowired
PasswordEncoder passwordEncoder;
@Bean
BCryptPasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
NoUniqueBeanDefinitionException: No qualifying bean of type 'o.s.s.c.p.PasswordEncoder' available: expected single matching bean but found 2: bcryptPasswordEncoder,md4PasswordEncoder
@Autowired
PasswordEncoder bcrypt;
@Autowired
PasswordEncoder md4;
@Bean
public PasswordEncoder bcryptPasswordEncoder()
{
return new BCryptPasswordEncoder();
}
@Bean
public PasswordEncoder md4PasswordEncoder()
{
return new Md4PasswordEncoder();
}
@Autowired
@Qualifier("bcryptPasswordEncoder")
PasswordEncoder bcrypt;
@Autowired
@Qualifier("md4PasswordEncoder")
PasswordEncoder md4;
@Bean
public PasswordEncoder bcryptPasswordEncoder()
{
return new BCryptPasswordEncoder();
}
@Bean
public PasswordEncoder md4PasswordEncoder()
{
return new Md4PasswordEncoder();
}
Here Field name acts as qualifier and helps when there are multiple beans of same type.
@Autowired
PasswordEncoder bcryptPasswordEncoder;
@Autowired
PasswordEncoder md4PasswordEncoder;
@Bean
public PasswordEncoder bcryptPasswordEncoder()
{
return new BCryptPasswordEncoder();
}
@Bean
public PasswordEncoder md4PasswordEncoder()
{
return new Md4PasswordEncoder();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With