SpringSecurity 提示ProviderNotFoundException: No AuthenticationProvider found for ****
Posted 在奋斗的大道
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringSecurity 提示ProviderNotFoundException: No AuthenticationProvider found for ****相关的知识,希望对你有一定的参考价值。
今天在实现SpringSecurity 集成多种认证方式:密码模式+ 验证码模式 时,密码模式正常返回执行并返回Token ,验证码模式:总是提示上述错误信息:ProviderNotFoundException: No AuthenticationProvider found for ****
问题解决:
报错代码发生在:ProviderManager.authenticate()方法的235行,错误源码输出如下:
源码上已经标识产生错误的原因: provider.authenticate(authentication) 代码中provider 为null 或者parent.authenticate(authentication) 代码中 parent 为空触发错误信息。
ProviderManager.java 类实例化详解分析:
第一步:WebSecurityConfigurerAdapter适配器类中有一个config方法
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
// 加入自定义的安全认证
auth.userDetailsService(this.authUserDetailsService)
.passwordEncoder(this.passwordEncoder())
.and()
.authenticationProvider(smsAuthenticationProvider())
.authenticationProvider(authenticationProvider());
第二步:可以通过AuthenticationManagerBuilder对象的authenticationProvider方法添加AuthenticationProvider认证对象,看下authenticationProvider方法:
private List<AuthenticationProvider> authenticationProviders = new ArrayList<>();
public AuthenticationManagerBuilder authenticationProvider(
AuthenticationProvider authenticationProvider)
this.authenticationProviders.add(authenticationProvider);
return this;
第三步:上面的是将AuthenticationProvider对象加入认证链中,下面的代码就是创建ProviderManager对象并初始化认证连:
@Override
protected ProviderManager performBuild() throws Exception
if (!isConfigured())
logger.debug("No authenticationProviders and no parentAuthenticationManager defined. Returning null.");
return null;
ProviderManager providerManager = new ProviderManager(authenticationProviders,
parentAuthenticationManager);
if (eraseCredentials != null)
providerManager.setEraseCredentialsAfterAuthentication(eraseCredentials);
if (eventPublisher != null)
providerManager.setAuthenticationEventPublisher(eventPublisher);
providerManager = postProcess(providerManager);
return providerManager;
通过上述三步,完成ProviderManager 实例化过程。
错误代码:
WebSecurityConfig 配置:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
@Qualifier("userDetailServiceImpl")
private UserDetailsService userDetailService;
/**
* 自定义Provider
*/
@Autowired
private VerificationCodeProvider verificationCodeProvider;
/**
* 认证
*
* @return
*/
@Bean
public AuthenticationProvider authenticationProvider()
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
//对默认的UserDetailsService进行覆盖
authenticationProvider.setUserDetailsService(userDetailService);
authenticationProvider.setPasswordEncoder(new PasswordEncoder()
// 对密码未加密
@Override
public String encode(CharSequence rawPassword)
return rawPassword.toString();
// 判断密码是否正确, rawPassword 用户输入的密码, encodedPassword 数据库DB的密码,当 userDetailService的loadUserByUsername方法执行完后执行
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword)
return rawPassword.toString().equalsIgnoreCase(encodedPassword);
);
return authenticationProvider;
在上述配置文件中,定义了两个Provider 但是在代码跟踪中仅仅发现DaoAuthenticationProvider 实例化成功,另外一个失败
正确代码:
WebSecurityConfig 配置:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
@Qualifier("userDetailServiceImpl")
private UserDetailsService userDetailService;
/**
* 自定义Provider
*/
@Autowired
private VerificationCodeProvider verificationCodeProvider;
/**
* 认证
*
* @return
*/
@Bean
public AuthenticationProvider authenticationProvider()
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
//对默认的UserDetailsService进行覆盖
authenticationProvider.setUserDetailsService(userDetailService);
authenticationProvider.setPasswordEncoder(new PasswordEncoder()
// 对密码未加密
@Override
public String encode(CharSequence rawPassword)
return rawPassword.toString();
// 判断密码是否正确, rawPassword 用户输入的密码, encodedPassword 数据库DB的密码,当 userDetailService的loadUserByUsername方法执行完后执行
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword)
return rawPassword.toString().equalsIgnoreCase(encodedPassword);
);
return authenticationProvider;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
// TODO Auto-generated method stub
auth.authenticationProvider(authenticationProvider());
auth.authenticationProvider(verificationCodeProvider);
产生问题得到解决
以上是关于SpringSecurity 提示ProviderNotFoundException: No AuthenticationProvider found for ****的主要内容,如果未能解决你的问题,请参考以下文章
okta oauth2 Spring security 所有受保护的页面重定向到登录
SpringSecurity 提示ProviderNotFoundException: No AuthenticationProvider found for ****
(转)解决dubbox-demo-provider.xml报错的问题:提示Failed to read schema document