Spring Security---自动登录二次校验和持久化令牌

形成天才的决定因素应该是勤奋。—— 郭沫若


Spring Security为用户提供了方便的记住密码功能,将生成的rememberMeToken放入了cookie中,这也意味着只要token没有过期,一旦泄漏后就会产生安全风险。所以应该提供其它的校验进一步来加强系统的安全性。

二次校验

在用户自动登录后,可以通过对密码进行二次校验进而确保用户的真实性。尽管Spring Security提供了记住密码功能,但是也为我们提供了二次校验的功能。

思路是对一些查询等不进行修改操作的接口,此时我们允许通过二次登录的用户直接进行查看,但是对于一些修改数据的接口,此时要求验证密码后才允许操作。

假设有一个Controller,拥有三个接口,getData作为公开接口,登录后任何用户都可以访问。updateData接口需要验证密码后才可以访问,即使通过rememberMe登录,访问后仍然需要验证密码。getData需要通过rememberMe登录后才可以进行访问,直接通过密码登录是无法访问的。

@RestController
public class HelloController {
    @GetMapping("/getData")
    public String getData() {
        return "hello world";
    }
    @GetMapping("/updateData")
    public String updateData() {
        return "hello updateData";
    }
    @GetMapping("/rememberData")
    public String rememberData() {
        return "hello rememberData";
    }
}

配置:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .antMatchers("/rememberData").rememberMe()
            .antMatchers("/updateData").fullyAuthenticated()
            .anyRequest().authenticated()
            .and()
           ...
}

/rememberData是通过rememberMe方式登录后才可以访问
/updateData是通过账号密码登录后才可以访问

authenticated 和 fullyAuthenticated的区别:authenticated 表示登录后可以访问,不论登录方式,fullyAuthenticated表示只允许账号密码登录方式才可以访问,rememberMe登录是无法访问的。

持久化令牌

当用户勾选remember后进行登录时,我们可以生成一个持久化的令牌,当用户下次自动登录时,获取令牌进行验证。

这里有两个关键的值:series 和 tokenValue,它们都是用MD5散列过的随机字符串。用户登录成功后,产生的series是不会更新的,只有用户再次使用密码登录时才会进行更新。而tokenValue会在每个session中重新生成。由于每次session会更新token,因此也可以很好的解决多端登录问题。

PersistentRememberMeToken是持久化令牌的实体类。提供了四个字段:用户名、序列号、令牌和最后一次自动登录时间。
在这里插入图片描述
对应的Sql也在JdbcTokenRepositoryImpl进行了定义。
在这里插入图片描述
根据大佬Luke Taylor提供的实体类和Sql,对于持久化令牌的表结构有了更清楚的了解。

配置:

首先需要创建张persistent_logins表

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

注入数据库配置,创建JdbcTokenRepositoryImpl 实例并注入数据库。

@Autowired
DataSource dataSource;
@Bean
JdbcTokenRepositoryImpl jdbcTokenRepository() {
    JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
    jdbcTokenRepository.setDataSource(dataSource);
    return jdbcTokenRepository;
}

将JdbcTokenRepositoryImpl 注入配置文件中。

@Override
protected void configure(HttpSecurity http) throws Exception {
   http.rememberMe()
        .tokenRepository(jdbcTokenRepository())
        .and()
        ....
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值