【SpringSecuirty6.x】自动登录和注销登录

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 【SpringSecuirty6.x】自动登录和注销登录

关于网站的安全设计,通常是有一些矛盾点的。我们在作为某些系统开发者的同时,也在充当着另外一些系统的用户,一些感同身受的东西可以带来很多思考。

5.1、为什么需要自动登录

当我们在某个网站上注册账号时,网站会对我们设置的登录密码提出要求。例如,有的网站要求使用固定位数的纯数字密码,有的网站则强制要求用户使用英文+数字组合成的密码,甚至要求加一些特殊符号来组成密码。总体而言,设定一个密码并不困难,真正的困难总是在下次登录时才会遇到。要么想不出网站要求的密码格式是什么,要么还原不了设置密码时的思维状态。总之,在几次尝试登录失败之后,大部分人会选择找回密码,从而再次陷入如何设置密码的循环里。

为了尽可能减少用户重新登录的频率,在系统开发之初就需要考虑加入可以提升用户登录体验的功能。自动登录便是这样一个会给用户带来便利,同时也会给用户带来风险的体验性功能。

自动登录是将用户的登录信息保存在用户浏览器的cookie中,当用户下次访问时,自动实现校验并建立登录态的一种机制。

Spring Security提供了两种非常好的令牌:

◎ 用散列算法加密用户必要的登录信息并生成令牌。

◎ 数据库等持久性数据存储机制用的持久化令牌。

散列算法在Spring Security中是通过加密几个关键信息实现的。

其中,expirationTime指本次自动登录的有效期,key为指定的一个散列盐值,用于防止令牌被修改。通过这种方式生成cookie后,在下次登录时,Spring Security首先用Base64简单解码得到用户名、过期时间和加密散列值;然后使用用户名得到密码;接着重新以该散列算法正向计算,并将计算结果与旧的加密散列值进行对比,从而确认该令牌是否有效。

5.2、实现自动登录

1、散列加密方案

在Spring Security中加入自动登录的功能非常简单。

@Override
protected void configure(HttpSecurity http) throws Exception {
    //所有页面都是授予所有权限
    http.authorizeRequests()
            .antMatchers("/admin/api/**").hasRole("ADMIN")
            .antMatchers("/user/api/**").hasRole("USER")
            .antMatchers("/app/api/**").permitAll()
            .anyRequest().authenticated() //其他所有都需要授权才能访问
            .and()
                .formLogin()
                .loginPage("/login").permitAll() //1、指定登录页面的URL
                .defaultSuccessUrl("/") //2、登录成功后的页面
            .and().rememberMe().rememberMeParameter("rememberMe").userDetailsService(userDetailsService).and()
            .logout(); //3、退出功能
}

前提是已经实现了一个UserDetailsService。重启服务后访问受限API,这次在表单登录页中多了一个可选框,如图所示。

勾选“记住我”可选框,按照正常的流程登录,并在开发者工具中查看浏览器cookie,可以看到除JSESSIONID外多了一个值,如图所示。

这就是Spring Security默认自动登录的cookie字段。在不配置的情况下,过期时间是两个星期。

public abstract class AbstractRememberMeServices
    implements RememberMeServices, InitializingBean, LogoutHandler, MessageSourceAware {
  //两个星期
  public static final int TWO_WEEKS_S = 1209600;

Spring Security会在每次表单登录成功之后更新此令牌,具体处理方式在源码中有体现。

总体来说,这种方式不需要服务器花费空间来存储自动登录的相关数据,实现简单,安全性相对较高。但存在潜在风险,即如果该令牌在有效期内被盗取,那么用户的身份将完全暴露。

2、持久化令牌方案

持久化令牌方案在交互上与散列加密方案一致,都是在用户勾选Remember-me之后,将生成的令牌发送到用户浏览器,并在用户下次访问系统时读取该令牌进行认证。不同的是,它采用了更加严谨的安全性设计。

在持久化令牌方案中,最核心的是series和token两个值,它们都是用MD5散列过的随机字符串。不同的是,series仅在用户使用密码重新登录时更新,而token会在每一个新的session中都重新生成。

这样设计有什么好处呢?

首先,解决了散列加密方案中一个令牌可以同时在多端登录的问题。每个会话都会引发token的更新,即每个token仅支持单实例登录。

其次,自动登录不会导致series变更,而每次自动登录都需要同时验证series和token两个值,当该令牌还未使用过自动登录就被盗取时,系统会在非法用户验证通过后刷新token 值,此时在合法用户的浏览器中,该token值已经失效。当合法用户使用自动登录时,由于该series对应的token 不同,系统可以推断该令牌可能已被盗用,从而做一些处理。例如,清理该用户的所有自动登录令牌,并通知该用户可能已被盗号等。

相关文章
|
5月前
|
SQL 数据可视化 数据库
基于jsp+servlet的javaweb实现最基本的用户注册登陆注销功能
基于jsp+servlet的javaweb实现最基本的用户注册登陆注销功能
23 0
|
6月前
|
存储 前端开发
通过session实现用户的登录与登出功能
通过session实现用户的登录与登出功能
198 0
用户登录问题
用户登录问题
85 0
|
安全 数据安全/隐私保护
用户登录
用户登录
126 0
|
存储 数据安全/隐私保护 Python
用户登录的用户库
用户登录的用户库
57 0
|
NoSQL Java Redis
手机验证码登录
手机验证登录分为三个API接口,分别为:获取图片验证码、获取手机短信验证码、登录。 1.获取图片验证码:通过工具类生成图片验证码,将随机验证码保存到session中,将图片验证码转为base64码放到对应的entity字段里。
9161 0
|
关系型数据库 MySQL 数据库
【Django | allauth】登录_注册_邮箱验证_密码邮箱重置
【Django | allauth】登录_注册_邮箱验证_密码邮箱重置
【Django | allauth】登录_注册_邮箱验证_密码邮箱重置
|
数据采集
自动登录12306
简单的登录操作,等有空的话写一个自动登录的爬虫吧。 from lxml import etree from selenium import webdriver from selenium.
1023 0
|
Web App开发 前端开发 JavaScript