SpringBoot集成Spring Security(2)——自动登录

在上一章:SpringBoot集成Spring Security(1)——入门程序中,我们实现了入门程序,本篇为该程序加上自动登录的功能。

源码地址:https://github.com/jitwxs/blog_sample


Step1 修改login.html

在登陆页添加自动登录的选项,注意自动登录的name必须是remember-me

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登陆</title>
</head>
<body>
<h1>登陆</h1>
<form method="post" action="/login">
    <div>
        用户名:<input type="text" name="username">
    </div>
    <div>
        密码:<input type="password" name="password">
    </div>
    <div>
        <label><input type="checkbox" name="remember-me"/>自动登录</label>
        <button type="submit">立即登陆</button>
    </div>
</form>
</body>
</html>

Step2 两种实现方式

2.1 Cookie存储

这种方式十分简单,只要在WebSecurityConfig中的configure()方法添加一个rememberMe()即可,如下所示:

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 如果有允许匿名的url,填在下面
//                .antMatchers().permitAll()
                .anyRequest().authenticated()
                .and()
                // 设置登陆页
                .formLogin().loginPage("/login")
                // 设置登陆成功页
                .defaultSuccessUrl("/").permitAll()
                // 自定义登陆用户名和密码参数,默认为username和password
//                .usernameParameter("username")
//                .passwordParameter("password")
                .and()
                .logout().permitAll()
                // 自动登录
                .and().rememberMe();

        // 关闭CSRF跨域
        http.csrf().disable();
    }

当我们登陆时勾选自动登录时,会自动在cookie中保存一个名为remember-me的cookie,默认有效期为2周,其值是一个加密字符串:

自动登录

2.2 数据库存储

使用Cookie存储虽然很方便,但是大家都知道Cookie毕竟是保存在客户端的,很容易盗取,而且cookie的值还与用户名、密码这些敏感数据相关,虽然加密了,但是将敏感信息存在客户端,毕竟不太安全。

spring security还提供了remember me的另一种相对更安全的实现机制 :在客户端的cookie中,仅保存一个无意义的加密串(与用户名、密码等敏感数据无关),然后在数据库中保存该加密串-用户信息的对应关系,自动登录时,用cookie中的加密串,到数据库中验证,如果通过,自动登录才算通过。

首先需要创建一张表来存储token信息:

CREATE TABLE `persistent_logins` (
  `username` varchar(64) NOT NULL,
  `series` varchar(64) NOT NULL,
  `token` varchar(64) NOT NULL,
  `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`series`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

在WebSecurityConfig中注入dataSource,创建一个PersistentTokenRepository 的Bean:

@Autowired
private DataSource dataSource;

 @Bean
 public PersistentTokenRepository persistentTokenRepository(){
     JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
     tokenRepository.setDataSource(dataSource);
     // 如果token表不存在,使用下面语句可以初始化该表;若存在,会报错。
//        tokenRepository.setCreateTableOnStartup(true);
     return tokenRepository;
 }

config()中按如下所示配置自动登陆:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            // 如果有允许匿名的url,填在下面
//                .antMatchers().permitAll()
            .anyRequest().authenticated()
            .and()
            // 设置登陆页
            .formLogin().loginPage("/login")
            // 设置登陆成功页
            .defaultSuccessUrl("/").permitAll()
            // 自定义登陆用户名和密码参数,默认为username和password
//                .usernameParameter("username")
//                .passwordParameter("password")
            .and()
            .logout().permitAll()
            // 自动登录
            .and().rememberMe()
                .tokenRepository(persistentTokenRepository())
                // 有效时间:单位s
                .tokenValiditySeconds(60)
                .userDetailsService(userDetailsService);

    // 关闭CSRF跨域
    http.csrf().disable();
}

Step3 运行程序

勾选自动登录后,cookie和数据库中均存储了token信息:

运行结果

阅读更多
版权声明:本文为本人原创文章,未经本人允许不得转载,谢谢。 https://blog.csdn.net/yuanlaijike/article/details/80249869
个人分类: Java
所属专栏: Java Web升级之路
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭