Spring 启动 UserNotFound 消息

Spring boot UserNotFound message

我正在尝试在 spring 引导 (2.5.3) 中进行基本身份验证,并在数据库中找不到用户时调用 UserNotFoundException。

@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");
    }
}

但结果我收到消息“Bad Credential”。 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

我应该覆盖什么才能看到 UserNotFoundException 错误消息?

创建自定义 Auth 提供程序

    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();
    }
}

就像那里解释的那样https://www.baeldung.com/spring-security-authentication-provider

您可以将 AuthenticationProvider 配置为在找不到用户名时抛出 UsernameNotFoundException 而不是 BadCredentialsException

请注意,这被认为 不太安全

来自 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.

如果您选择这样做,下面是如何使用 setHideUserNotFoundExceptions

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