Home > other >  Spring boot UserNotFound message
Spring boot UserNotFound message

Time:09-25

I'm trying to make basic authentication in spring boot (2.5.3), and call UserNotFoundException when cant found user at DB.

@Override
public User findByUserName(String username){

    try {

        return (User) template.queryForObject("SELECT * FROM USERS WHERE email = ?",
                new BeanPropertyRowMapper(User.class), username);

    } catch (EmptyResultDataAccessException e) {
        throw new UsernameNotFoundException("User not found");
    }
}

But as a result I get message "Bad Credential". My exception has changed by BadCredential Exception.

public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {

private ObjectMapper objectMapper = new ObjectMapper();

@Override
public void onAuthenticationFailure(
        HttpServletRequest request,
        HttpServletResponse response,
        AuthenticationException ex) throws IOException, ServletException {

    response.setStatus(HttpStatus.UNAUTHORIZED.value());
    //HttpStatus.FORBIDDEN
    Map<String, Object> data = new HashMap<>();
    data.put(
            "timestamp",
            Calendar.getInstance().getTime());
    data.put(
            "exception",
            ex.getMessage());

    System.out.println(ex.getClass());

    response.getOutputStream()
            .println(objectMapper.writeValueAsString(data));
}

class org.springframework.security.authentication.BadCredentialsException

What should I override to make ability to see UserNotFoundException error message ?

CodePudding user response:

Make custom Auth provider

    public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private Repository repository;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String name = authentication.getName();
        String password = authentication.getCredentials().toString();

        User user = repository.findByUserName(name);

        if(!encoder().matches(password, user.getPassword())){
            throw new BadCredentialsException("Bad credentials");
        }

        return new UsernamePasswordAuthenticationToken(user, password,
                        Arrays.asList(new SimpleGrantedAuthority("USER_ROLE")));
        
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

    @Bean
    public PasswordEncoder encoder() {
        return new BCryptPasswordEncoder();
    }
}

Like there explained https://www.baeldung.com/spring-security-authentication-provider

CodePudding user response:

You can configure the AuthenticationProvider to throw a UsernameNotFoundException instead of a BadCredentialsException when the username is not found.

Be aware that this is considered less secure.

From the setHideUserNotFoundExceptions Javadoc:

By default the AbstractUserDetailsAuthenticationProvider throws a BadCredentialsException if a username is not found or the password is incorrect. Setting this property to false will cause UsernameNotFoundExceptions to be thrown instead for the former. Note this is considered less secure than throwing BadCredentialsException for both exceptions.

If you choose to do this, below is an example of how to use setHideUserNotFoundExceptions

@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
    DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    provider.setUserDetailsService(customUserDetailsService);
    provider.setPasswordEncoder(customPasswordEncoder);
    provider.setHideUserNotFoundExceptions(false) ;
    return provider;
}
  • Related