今天項目提出了一個改進的需求就是說登錄的時候要求提示具體的錯誤,是用戶名輸入錯誤,導致的用戶不存在,還是密碼輸入錯誤,這些是需要進行提示的。
首先需要看源碼。
DaoAuthenticationProvider ——》 AbstractUserDetailsAuthenticationProvider的authenticate函數
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication, () -> {
return this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.onlySupports", "Only UsernamePasswordAuthenticationToken is supported");
});
String username = authentication.getPrincipal() == null ? "NONE_PROVIDED" : authentication.getName();
boolean cacheWasUsed = true;
UserDetails user = this.userCache.getUserFromCache(username);
if (user == null) {
cacheWasUsed = false;
try {
user = this.retrieveUser(username, (UsernamePasswordAuthenticationToken)authentication);
} catch (UsernameNotFoundException var6) {
this.logger.debug("User '" + username + "' not found");
if (this.hideUserNotFoundExceptions) {
throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
}
throw var6;
}
Assert.notNull(user, "retrieveUser returned null - a violation of the interface contract");
}
其中的hideUserNotFoundExceptions默認是true,
if (this.hideUserNotFoundExceptions) {
throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
}
也就是說用戶不存在也會被拋出密碼錯誤信息。
解決辦法:
在security配置類中編寫DaoAuthenticationProvider,將hideUserNotFoundExceptions設置成false
/**
* 在security配置類中編寫DaoAuthenticationProvider,將hideUserNotFoundExceptions設置成false
* @return
*/
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider(){
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setHideUserNotFoundExceptions(false);//將這個異常設置false,這樣就可以拋出用戶不存在的異常
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
return daoAuthenticationProvider;
}
重寫configure
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());//在重寫的configure方法中配置DaoAuthenticationProvider
//auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
但是注意,要把之前的註釋掉,不然還是會有錯誤。
還有一處就是需要改一下,就是UserDetailServiceImpl裏的函數的實現,需要判斷當前輸入是否有這個用戶,沒有的話就要拋出沒有用戶的異常,springsecurity沒有找出對應用戶的功能。
參考
https://blog.csdn.net/weixin_42198239/article/details/101110543