SpringSecurity(七):添加验证码

(一) AuthenticationProvider实现类

经过之前的认证流程分析,我们知道了认证主要是在AuthenticationProvider中的authenticate中完成的,那么我们只需要在这个方法中添加一个验证码校验即可

//新建一个AuthenticationProvider实现类,因为是在账号/密码登录的方式上添加验证码 因此继承DaoAuthenticationProvider即可
public class KaptchaAuthenticationProvider extends DaoAuthenticationProvider{
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException{
//得到HttpServletRequest
HttpServletRequest req=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();

//取出前端发送的kaptcha
String kaptcha=req.getParameter("kaptcha");

//取出我们保存的kaptcha,这里是保存在session中

String sessionKaptcha=(String)req.getSession().getAttribute("kaptcha");

//验证 验证码是否相同

if(kaptcha!=null && sessionKapthca!=null && kaptcha.equals(sessionKaptcha)){
    //由父类DaoAuthenticationProvider的authenticate方法校验账号密码
    return  super.authenticate(authentication);
}
//验证码 不通过  抛出异常
throws new AuthenticationServiceException("验证码错误");
}
}

接着为这个AuthenticationProvider实现类 注入UserDetailsService,并注册到ProciderManager中

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
MyUserDetailsService1 userDetailsService;

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception{

    KaptchaAuthenticationProvider provider=new KaptchaAuthenticationProvider();
    provider.setUserDetailsService(userDetailsService);

    //创建ProviderManager,并注入AuthenticationProvider
    ProviderManager manager=new ProviderManager(provider);
    return manager;

}

......省略configure方法
}

我们为什么不直接重写DaoAuthenticationProvider的additionalAuthenticationChecks方法呢?

需要注意的是我们希望通过验证码过滤掉一些非法请求,即校验验证码应该在查询数据库之前,如果重写additionalAuthenticationChecks方法,此时已经查询数据库了,验证码就起不到拦截而已请求的作用了!

posted @ 2021-05-20 20:26  刚刚好。  阅读(719)  评论(0)    收藏  举报