The following is the implementation of SecurityFilterChain
:
@EnableWebSecurity
@Configuration
public class WebSecurity {
private final UserService userDetailsService;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
public WebSecurity(UserService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
this.userDetailsService = userDetailsService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
AuthenticationManagerBuilder authenticationManagerBuilder =
http.getSharedObject(AuthenticationManagerBuilder.class);
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(bCryptPasswordEncoder);
http
.csrf(csrf -> csrf.disable())
.authorizeRequests()
.requestMatchers(HttpMethod.POST, "/users").permitAll()
.anyRequest().authenticated();
return http.build();
}
}
And the UserService
implementation looks like this:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private Utils utils;
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Override
public UserDto createUser(UserDto userDto) {
UserEntity exists = userRepository.findByEmail(userDto.getEmail());
if(exists != null){
throw new RuntimeException("Record already exists" );
}
UserEntity userEntity = new UserEntity();
BeanUtils.copyProperties(userDto, userEntity);
String publicUserId = utils.generateUserId(30);
userEntity.setUserId(publicUserId);
userEntity.setEncryptedPassword(bCryptPasswordEncoder.encode(userDto.getPassword()));
UserEntity storedUserEntity = userRepository.save(userEntity);
UserDto returnValue = new UserDto();
BeanUtils.copyProperties(storedUserEntity, returnValue);
return returnValue;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserEntity userEntity = userRepository.findByEmail(username);
if(userEntity == null){
throw new UsernameNotFoundException(username);
}
return new User(username, userEntity.getEncryptedPassword(), new ArrayList<>());
}
}
Now, I am able to create new users via /users
endpoint. However, if I try to create the user with existing email, then I am getting 403 error. I was expecting a error with stacktrace. Why 403?
This can happen due to securityconfiguration class is not added in springboot 3 , websecurityconfigureadaptor is deprecated so you cant use old definition of class .
Below bean definition can be used instead of overriding configure method from websecurityconfigureadaptor
https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter