Issue
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 ?
Solution
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 aBadCredentialsException
if a username is not found or the password is incorrect. Setting this property tofalse
will causeUsernameNotFoundException
s to be thrown instead for the former. Note this is considered less secure than throwingBadCredentialsException
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;
}
Answered By - Eleftheria Stein-Kousathana
Answer Checked By - David Goodson (JavaFixing Volunteer)