spring security实现记住我下次自动登陆功能

spring security实现记住我下次自动登陆功能

上一篇: spring security的BCryptPasswordEncoder加密和对密码验证的原理java

1、原理分析

第一次登录时,若是用户勾选了readme选项,登录成功后springsecurity会生成一个cookie返回给浏览器端,浏览器下次访问时若是携带了这个cookie,springsecurity就会放行此次访问。git

2、实现方式

2.1 简单实现方式

(1) 在springsecurity的配置文件中,http节点下增长一个remember-me配置spring

<security:http auto-config="true" use-expressions="false">
        <!-- 配置连接地址,表示任意路径都须要ROLE_USER权限,这里能够配置
         一个逗号隔开的角色列表-->
        <security:intercept-url pattern="/**" access="ROLE_USER"/>

        <!--自定义登陆页面-->
        <security:form-login login-page="/login.html" login-processing-url="/login"
                             username-parameter="username" password-parameter="password"
                             authentication-failure-forward-url="/failed.html"
                             default-target-url="/index.html"

        />
        <!--关闭csrf,默认是开启的-->
        <security:csrf disabled="true"/>

        <security:remember-me remember-me-parameter="remembermeParamater" />
        <!-- 退出 -->
        <security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.html"/>
    </security:http>

其中remember-me-parameter="remembermeParamater"指定前台传递的是否rememberme的参数名,前台要传递的参数值是true或falsesql

(2)前台登陆页面上增长一个checkbox数据库

<form action="/login" method="post">
        用户名:<input type="text" name="username" placeholder="请输入用户名"><br>
        密 码:<input type="password" name="password" placeholder="请输入密码"><br>
        记住我:<input id="_spring_security_remember_me" type="checkbox" name="remembermeParamater" value="true">
        <input type="submit" value="登陆">
    </form>

checkbox的name属性要和上边配置文件中的remember-me-parameter="remembermeParamater"保持一致。express

(3)测试浏览器

启动工程,进行登陆,登陆成功后观察cookie,会发现服务器端返回了一个名为remember-me的cookie服务器

如今关闭浏览器,再次打开并访问,只要不清除cookie就能够直接访问资源,不须要从新登陆。cookie

这种方式有个弊端,浏览器端要携带的这个cookie值服务端是存放在内存中的,并无进行持久化,因此若是服务重启后服务器端存储的这个值就会丢失,浏览器端的rememberme就会失效。为了解决这个问题就须要将服务器端生成的这个cookie值持久化到数据库中。

2.2 数据库实现方式

(1)建立一张表用来持久化rememberme的记录

-- 建立记录rememberme记录的表
CREATE TABLE persistent_logins
(
  username  VARCHAR(64),
  series   VARCHAR(64),
  token     VARCHAR(64),
  last_used DATE 
 );

(2)将spring-security 配置文件中的rememberme标签的内容改成以下内容

<security:remember-me remember-me-parameter="remembermeParamater" data-source-ref="dataSource"
                              token-validity-seconds="86400"/>

data-source-ref="dataSource"用来指定数据源,spring-security经过数据源来操做数据库中的persistent_logins表

token-validity-seconds表示rememberme的有效时间,以秒为单位,这里的86400=24*3600表示一天

(3)测试

启动工程,进行登陆,登陆成功后会在persistent_logins表中生成一条记录,


关闭浏览器再次访问时会根据浏览器中携带的cookie值来查找数据库中的这条记录,若是查询到了就认证经过

3、区分是密码登陆仍是rememberme登陆

在用户进行一些敏感操做时,须要区分是不是rememberme登陆,若是是须要让用户跳转到登陆页面。

在congtroller层提供一个方法来进行判断

@GetMapping("/isRemembermeUser")
public boolean isRemembermeUser(){
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if(authentication==null){
        return false;
    }
    //判断当前用户是不是经过rememberme登陆,是返回true,否返回false
    return RememberMeAuthenticationToken.class.isAssignableFrom(authentication.getClass());
}

先使用密码登陆,访问http://localhost/user/isRemembermeUser.do,后台接口返回false,再关闭浏览器再次访问这个地址,后台接口返回true,表示此次是使用rememberme进行的认证。

测试工程代码的地址:工程示例

相关文章
相关标签/搜索