Reputation: 484
I am getting the following error message:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 1 of constructor in dev.guilder.SnowballCalculator.UserManagement.Service.AppUserService required a bean of type 'org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' in your configuration.
My WebSecurityConfig is:
package dev.guilder.SnowballCalculator.Configurations;
import dev.guilder.SnowballCalculator.UserManagement.Service.AppUserService;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@AllArgsConstructor
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final AppUserService appUserService;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
@Override
protected void configure(HttpSecurity http) throws Exception {
//TODO: properly autorize these pages
http.authorizeRequests()
/*
.antMatchers("/*").permitAll()
.anyRequest().permitAll()
*/
.antMatchers("/admin/**", "/adminDashboard").authenticated()
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.antMatchers("/**", "/home", "/about", "/pricing", "/css/**", "/js/**", "/registration", "/api/**").permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider =
new DaoAuthenticationProvider();
provider.setPasswordEncoder(bCryptPasswordEncoder);
provider.setUserDetailsService(appUserService);
return provider;
}
}
My AppUserService is:
package dev.guilder.SnowballCalculator.UserManagement.Service;
import dev.guilder.SnowballCalculator.UserManagement.Entitys.AppUser;
import dev.guilder.SnowballCalculator.UserManagement.Entitys.AppUserRepository;
import dev.guilder.SnowballCalculator.UserManagement.Entitys.ConfirmationToken;
import dev.guilder.SnowballCalculator.UserManagement.Service.Registration.ConfirmationTokenService;
import lombok.AllArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.UUID;
@Service
@AllArgsConstructor
public class AppUserService implements UserDetailsService {
private final static String USER_NOT_FOUND_MSG =
"user with email %s not found";
private final AppUserRepository appUserRepository;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
private final ConfirmationTokenService confirmationTokenService;
@Override
public UserDetails loadUserByUsername(String email)
throws UsernameNotFoundException {
return appUserRepository.findByEmail(email)
.orElseThrow(() ->
new UsernameNotFoundException(
String.format(USER_NOT_FOUND_MSG, email)));
}
public String signUpUser(AppUser appUser) {
boolean userExists = appUserRepository
.findByEmail(appUser.getEmail())
.isPresent();
if (userExists) {
// TODO check of attributes are the same and
// TODO if email not confirmed send confirmation email.
throw new IllegalStateException("email already taken");
}
String encodedPassword = bCryptPasswordEncoder
.encode(appUser.getPassword());
appUser.setPassword(encodedPassword);
appUserRepository.save(appUser);
String token = UUID.randomUUID().toString();
ConfirmationToken confirmationToken = new ConfirmationToken(
token,
LocalDateTime.now(),
LocalDateTime.now().plusMinutes(15),
appUser
);
confirmationTokenService.saveConfirmationToken(
confirmationToken);
// TODO: SEND EMAIL
return token;
}
public int enableAppUser(String email) {
return appUserRepository.enableAppUser(email);
}
}
If I put the solutions mention in Consider defining a bean of type 'org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' in your configuration or Error: Required a bean of type 'org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' that could not be found
I either get the same error or I get:
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| webSecurityConfig defined in file [C:\Users\Guilder W. Milliner\Repositories\SC-403_SnowBallalculator_CapstoneProject\build\classes\java\main\dev\guilder\SnowballCalculator\Configurations\WebSecurityConfig.class]
↑ ↓
| appUserService defined in file [C:\Users\Guilder W. Milliner\Repositories\SC-403_SnowBallalculator_CapstoneProject\build\classes\java\main\dev\guilder\SnowballCalculator\UserManagement\Service\AppUserService.class]
└─────┘
Action:
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
Upvotes: 0
Views: 2812
Reputation: 21883
In you WebSecurityConfig
remove the following line
private final BCryptPasswordEncoder bCryptPasswordEncoder;
and add
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
And use the bean below
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider =
new DaoAuthenticationProvider();
// using bCryptPasswordEncoder()
provider.setPasswordEncoder(bCryptPasswordEncoder());
provider.setUserDetailsService(appUserService);
return provider;
}
Upvotes: 2