Search code examples
javaspringspring-bootspring-securityspring-data-jpa

Spring Boot Getting 403 on Error inside the Service


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?

enter image description here


Solution

  • 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