认证篇:Spring Security 自定义验证码登录(下)之登录流程讲解

图 1-0 总结图

本篇为自定义验证码登录的下篇,主要会对自定义登录的流程进行讲解;我们曾在认证(二):表单登录的源码解析中对 Spring Security的认证流程有过比较详细的学习。

“模仿不是创作,但创作不能不有模仿”————周谷城。

我们可以从表单登录认证流程中寻找灵感,定制化开发出验证码登录认证。

流程分析

首先先回顾一下表单登录的认证流程:

图1-1 表单登录认证流程

大致上有这么几个比较核心的类/接口:

  1. UsernamePasswordAuthenticationFilter过滤器,用以捕获表单登录请求。

  2. UsernamePasswordAuthenticationToken表单登录token,用以匹配对应的认证Provider

  3. AuthenticationManager认证管理器,即不干活的"大佬"。

  4. ProviderManager管理领域的"二把手"。

  5. DaoAuthenticationProvider执行表单登录认证的Provider,即真正干活的"小弟"。

分析得出,除了管理领域的“大佬” AuthenticationManager和 “二把手” ProviderManager不需要我们额外实现,剩下的我们都需要自定义实现。

基于这个结论,我大致描绘出验证码登录认证的流程图:
图 1-2 验证码登录认证类比图

自定义验证码认证,需要将FilterToken以及 Provider嵌入到整个认证链路中;所以自定义认证需要做以下3件事情:

  • 自定义ValidateCodeAuthenticationFilter,类比UsernamePasswordAuthenticationFilter

  • 自定义SmsValidateCodeAuthenticationToken,类比UsernamePasswordAuthenticationToken

  • 自定义SmsValidateCodeAuthenticationProvider,类比DaoAuthenticationProvider

流程实现

通过上面的流程分析,我们可以大致弄清楚需要做什么事情了;那么 Just Do it!!!

自定义ValidateCodeAuthenticationFilter

ValidateCodeAuthenticationFilter拦截器的作用是:从请求中获取验证码进行验证。

可能有人会有疑问:从请求中获取验证码进行验证,听起来似乎是 Provider做的事情呀,为什么会放在这里呢(类比表单登录的 Filter只是做了请求参数到 Token的转换,真实的校验是在 Provider中)?

这里这么做是为了复用验证码的功能,在很多时候我们都用使用验证码的需求:修改密码、付款…… 如果将验证码的校验放在 Provider模块的话,一定程度上限制了验证码只能用于登录。

ValidateCodeAuthenticationFilter.class

/**
 * 验证码拦截器(自定义springSecurity过滤器实现,在登录之前进行验证码验证)
 *
 *  InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,
 *  凡是继承该接口的类,在初始化bean的时候都会执行该方法。
 *
 * @author 小奇
 * @date 2020/10/08
 **/
@Slf4j
@Component("ValidateCodeAuthenticationFilter")
public class ValidateCodeAuthenticationFilter extends OncePerRequestFilter implements InitializingBean {
   


    /**
     * key为请求的路径 map为验证码类型
     * 存放所有需要校验验证码的url(例如:验证码登录、支付时需要填写验证码等等……)
     */
    private Map<String, ValidateCodeEnum> urlMap = new HashMap<>(8);

    /**
     * 验证请求url与配置的url是否匹配的工具类
     */
    private AntPathMatcher pathMatcher = new AntPathMatcher();

    /**
     * 通过配置文件的方式配置 一些需要验证码认证的url
     */
    @Autowired
    private SecurityProperties securityProperties;

    /**
     * 认证失败处理器
     */
    @Autowired
    private WebAuthenticationFailHandler failureHandler;

    /**
     * Holder是对Processor的更上一级调用
     */
    @Autowired
    private ValidateCodeProcessorHolder validateCodeProcessorHolder;

    /**
     * 初始化本类的Bean对象时候,会执行该方法进行相应的初始化
     */
    @Override
    public void afterPropertiesSet() {
   
        initUrlMap(securityProperties.getCode().getImage().getUrls(), ValidateCodeEnum.IMAGE);
        initUrlMap(securityProperties.getCode().getSms().getUrls(), ValidateCodeEnum.SMS);
    }

    /**
     * 拦截 校验验证码
     *
     * @param request
     * @param response
     * @param chain
     
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值