Spring Security 中 UserNameNotFoundException 异常未正常抛出

一、故障现象

1.代码:

Reference:
org.springframework.security.core.userdetails.UserDetailsService;


//代码片段:
@Service
public class UserRepositoryUserDetailsService implements UserDetailsService {

    private final UserRepository userRepository;

    public UserRepositoryUserDetailsService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user != null) {
            return user;
        }
        //throw new BadCredentialsException("帐号不存在,请重新输入");
        throw new UsernameNotFoundException("User '" + username + "' not found!");
    }
}

2.现象:

当登录用户不存在时,应当回显 "User 'username' not found! ",但实际显示为 Bad credentials 。

二、原因

1.源码:

Reference:
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider#authenticate;

//代码片段:
catch (UsernameNotFoundException ex) {
   this.logger.debug("Failed to find user '" + username + "'");
   if (!this.hideUserNotFoundExceptions) {
      throw ex;
   }
   throw new BadCredentialsException(this.messages
         .getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
}

2.释义:

在 AbstractUserDetailsAuthenticationProvider 中,hideUserNotFoundExceptions 默认为 true,所以没有抛出 UsernameNotFoundException 这个异常,而是将其转换为 BadCredentialsException

三、解决方案

1.修正:

Reference:
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
org.springframework.security.core.userdetails.UserDetailsService;
org.springframework.security.crypto.password.PasswordEncoder;
org.springframework.security.authentication.dao.DaoAuthenticationProvider;

//代码片段:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("userRepositoryUserDetailsService")
    private UserDetailsService userDetailsService;

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

    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setHideUserNotFoundExceptions(false);
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(this.passwordEncoder());
        return provider;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(daoAuthenticationProvider());
    }
}

2.释义:

将hideUserNotFoundExceptions 设置为 false;并于 Spring Security 的 WebSecurityConfigurer 中进行配置

如果您在浏览过程中,发现有侵权或者不合适的链接,请联系我们处理,谢谢
备案 域名访问错误!