新写了一个项目,spring boot整合spring security时密码认证失败,报了一个ProviderNotFoundException进到了failureHandler的else里面
org.springframework.security.authentication.ProviderNotFoundException:
No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken
我定义了一个接口IUsersService,在IUsersService继承了UserDetailsService。
定义了一个UsersServiceImpl实现类实现IUsersService的loadUserByUsername方法。
在debug时,发现没有进到loadUserByUsername这个方法,
.failureHandler((request, response, exception) -> {
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
RespBean respBean=null;
if(exception instanceof BadCredentialsException){
respBean=RespBean.error("用户名或密码不正确");
}else if(exception instanceof DisabledException){
respBean=RespBean.error("用户被禁用");
}else {
exception.printStackTrace();
}
response.getWriter().write(new ObjectMapper().writeValueAsString(respBean));
})
解决方法一
在过滤器链指定HttpSecurity的userDetailsService
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.userDetailsService(usersService)
.authorizeRequests()
.antMatchers("/**").authenticated()
.and().formLogin()
.loginProcessingUrl("/login")
解决方法二
这个报错本质上的错误,是使用接口继承了UserDetailsService,然后再实现这个接口
而不是在实现类直接实现UserDetailsService;
表面上看没什么问题,但是SpringBoot不会发现这个UserDetailsService的实现类UsersServiceImpl。
解决方法就是将UsersServiceImpl间接实现UserDetailsService改为UsersServiceImpl直接实现UserDetailsService即可
public interface IUsersService extends IService<Users>, UserDetailsService {
}
改为如下:
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements IUsersService, UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {