史上最简单的Spring Security教程(三十六):RememberMeAuthenticationFilter详解

 

前面我们讲了 记住我 登录方式,以及和其它登录方式相融合的多种登录形式,想必对 记住我 登录方式有了一个大致清晰的了解。本次我们就来说一下其中一个比较重要的 Filter,即 RememberMeAuthenticationFilter

RememberMeAuthenticationFilter 是 记住我 登录方式比较重要的类,其主要功能有 自动登录身份认证登录成功事件发布异常处理/登录失败 等。

另外,重要的一点是,该 Filter 执行有一个条件,就是当前用户尚未认证

if (SecurityContextHolder.getContext().getAuthentication() == null) {
    ......
}

下面就这几项重要功能分别加以说明。

当当前用户尚未登录时,先执行 自动登录 逻辑,即先调用 RememberMeServices 的 autoLogin 方法。

Authentication rememberMeAuth = rememberMeServices.autoLogin(request,
          response);

如果 rememberMeAuth 不为 null,则再执行身份认证。

rememberMeAuth = authenticationManager.authenticate(rememberMeAuth);

没忘了 AuthenticationManager 吧?前面详细讲过:史上最简单的Spring Security教程(二十七):AuthenticationManager默认实现之ProviderManager详解

身份认证成功(不发生异常)后,先将当前 Authentication 设置到 SecurityContextHolder 上下文中,然后再执行成功登录逻辑。

// Store to SecurityContextHolder
SecurityContextHolder.getContext().setAuthentication(rememberMeAuth);
​
onSuccessfulAuthentication(request, response, rememberMeAuth);

之后,便调用时间发布器,发布相关事件

// Fire event
if (this.eventPublisher != null) {
    eventPublisher
        .publishEvent(new InteractiveAuthenticationSuccessEvent(
            SecurityContextHolder.getContext()
            .getAuthentication(), this.getClass()));
}

然后,如果设置了 AuthenticationSuccessHandler ,则调用成功登录逻辑。没忘了 AuthenticationSuccessHandler 的用法吧?之前我们同样也介绍过:史上最简单的Spring Security教程(五):成功登录SuccessHandler高级用法

此外,如果想跳转到某个特定页面,而不是用户一开始访问的页面,怎么办呢?同样是在 AuthenticationSuccessHandler 中设置 defaultTargetUrl ,之前也详细讲解过,并且也画了一个详细的流程图:史上最简单的Spring Security教程(四):成功登录页面

接下来,便是异常处理/登录失败了。捕获到身份认证过程中的异常后,进行 异常处理/登录失败 相关处理

catch (AuthenticationException authenticationException) {
    if (logger.isDebugEnabled()) {
        logger.debug(
            "SecurityContextHolder not populated with remember-me token, as "
            + "AuthenticationManager rejected Authentication returned by RememberMeServices: '"
            + rememberMeAuth
            + "'; invalidating remember-me token",
            authenticationException);
    }
​
    rememberMeServices.loginFail(request, response);
​
    onUnsuccessfulAuthentication(request, response,
                                 authenticationException);
}

最后,如果不满足该 Filter 触发条件,即当前用户已经身份认证完成或存在其身份认证信息,或者 调用 自动登录 后得不到相应的结果,即 自动登录 失败,便会调用后续的 Filter。

else {
    if (logger.isDebugEnabled()) {
        logger.debug("SecurityContextHolder not populated with remember-me token, as it already contained: '"
                     + SecurityContextHolder.getContext().getAuthentication() + "'");
    }
​
    chain.doFilter(request, response);
}

如果想自定义 登录成功 、登录失败(注意不是AuthenticationSuccessHandler、AuthenticationFailureHandler 怎么办呢?当然是一样的逻辑咯,继承此 Filter 后,实现两个方法即可。

protected void onSuccessfulAuthentication(HttpServletRequest request,
      HttpServletResponse response, Authentication authResult) {
}
​
......
    
protected void onUnsuccessfulAuthentication(HttpServletRequest request,
      HttpServletResponse response, AuthenticationException failed) {
}

RememberMeAuthenticationFilter 的主要功能介绍完毕。

其它详细源码,请参考文末源码链接,可自行下载后阅读。

我是银河架构师,十年饮冰,难凉热血,愿历尽千帆,归来仍是少年! 

如果文章对您有帮助,请举起您的小手,轻轻【三连】,这将是笔者持续创作的动力源泉。当然,如果文章有错误,或者您有任何的意见或建议,请留言。感谢您的阅读!

 

源码

 

github

https://github.com/liuminglei/SpringSecurityLearning/tree/master/36

gitee

https://gitee.com/xbd521/SpringSecurityLearning/tree/master/36

 

 

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值