史上最简单的Spring Security教程(三十一):默认用户名密码登录新增RememberMe(记住我)选项

在我们登录一些网站的时候,通常会有一个选项-记住我。选中该选项,登录成功后,无论浏览器关闭,还是服务重启,只要不清除浏览器缓存信息,且Cookie在网站预设的有效期时间内,则无需重新登录网站即可访问其资源。

其实,Spring Security 框架也可以实现相同的功能。本文便基于 Spring Security 框架默认的用户名密码登录为基础,为其添加 RememberMe(记住我)选项。

首先,修改登录页面,将 记住我 复选框 name 属性修改为 remember-me

<form th:action="@{/login}" method="post" th:method="post" class="mt-1">
  ......
  <div class="checkbox">
    <label><input type="checkbox" name="remember-me"> 记住我</label>
  </div>
  ......
</form>

为何要修改 name 属性修改为 remember-me,而不是别的什么名字呢?其实,原因并不复杂,简单点来说,这是 Spring Security 框架默认的 记住我 复选框的名称。当然,你也可以命名为别的名字,然后把相关配置也同样修改为此名字即可。

还记得 UsernamePasswordAuthenticationFilter 类有一个 rememberMeServices 属性吗?初始值为 NullRememberMeServices

private RememberMeServices rememberMeServices = new NullRememberMeServices();

在身份认证成功后,会执行 successfulAuthentication 方法。这在文章史上最简单的Spring Security教程(二十五):UsernamePasswordAuthenFilter详解中也有提及,不过并没有过多的解释。此方法执行过程中,便会调用 RememberMeServices 接口的 loginSuccess 方法。

protected void successfulAuthentication(HttpServletRequest request,
      HttpServletResponse response, FilterChain chain, Authentication authResult)
      throws IOException, ServletException {
​
    if (logger.isDebugEnabled()) {
        logger.debug("Authentication success. Updating SecurityContextHolder to contain: "
                     + authResult);
    }
​
    SecurityContextHolder.getContext().setAuthentication(authResult);
​
    rememberMeServices.loginSuccess(request, response, authResult);
​
    // Fire event
    if (this.eventPublisher != null) {
        eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(
            authResult, this.getClass()));
    }
​
    successHandler.onAuthenticationSuccess(request, response, authResult);
}

RememberMeServices 接口的 loginSuccess 便会判断登录页的 记住我 复选框是否选中,选中的情况下,才会执行后续逻辑。

public final void loginSuccess(HttpServletRequest request,
      HttpServletResponse response, Authentication successfulAuthentication) {
​
    if (!rememberMeRequested(request, parameter)) {
        logger.debug("Remember-me login not requested.");
        return;
    }
​
    onLoginSuccess(request, response, successfulAuthentication);
}

注意,这是 RememberMeServices 接口的 抽象实现类 AbstractRememberMeServices 中的实现逻辑,由于 UsernamePasswordAuthenticationFilter 类  rememberMeServices 属性的初始值为 NullRememberMeServices,其并没有继承 AbstractRememberMeServices 类,只是空的实现。因此,需要配置 UsernamePasswordAuthenticationFilter 类中的 rememberMeServices 属性为具体的 RememberMeServices 接口实现。

然后,调整一下 Spring Security 配置,新增 rememberMe 的相关配置。

protected void configure(HttpSecurity http) throws Exception {
    http
        ......
        .rememberMe()
        .userDetailsService(userDetailsService())
        .tokenValiditySeconds(14 * 24 * 60 * 60)
        ......
​
}

token默认有效期为两周,即14天,与 Spring Security 默认配置相同。

万事俱备,启动系统,访问登录页面,尝试一下。

输入用户名、密码,最重要的不要忘了,勾选 记住我 选项,系统正常调转到了系统首页。

关闭浏览器,直接访问系统首页,此时,仍然可以直接访问,并没有重定向到登录页,无需输入用户名、密码。相同的,重启应用之后,同样可以直接访问系统首页,也无需再次登录。

 记住我 改造完成。

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

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

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

源码

github

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

gitee

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

如果喜欢我们的文章

可以关注我们

也可以点击右下角的在看告诉我们

期待与您相遇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值