Spring Security 5.7.5版本
RememberMeAuthenticationFilter.doFilter方法包含了核心逻辑。
RememberMeAuthenticationFilter在UsernamePasswordAuthenticationFilter之后执行。
- 从SecurityContextHolder获取的Authentication为null时,会执行rememberMeServices.autoLogin(request,response)方法获取Authentication对象。
- autoLogin默认的实现类是AbstractRememberMeServices。
- 首先将remember-me cookie做base64解码后以:分隔成字符串数组,再进行URLDecode。
- 执行子类的processAutoLoginCookie(cookieTokens,request,response)方法获取UserDetails对象。
- 封装成Authentication对象
- processAutoLoginCookie的实现类有两个,TokenBasedRememberMeServices和PersistentTokenBasedRememberMeServices。
- TokenBasedRememberMeServices.processAutoLoginCookie方法。这个类只在浏览器存储一个名为remember-me的cookie。cookie字符串数组的数量应为3,分别是username, expireTime, signature[base64(username + ":" + expiryTime + ":" + Md5Hex(username + ":" + expiryTime + ":" + password + ":" + key))]。根据用户名调用UserDetailServices.loadUserByUsername方法查询UserDetails,生成签名并与cookie的签名值比较,如果匹配则返回UserDetails对象,否则抛出InvalidCookieException异常。
- PersistentTokenBasedRememberMeServices.processAutoLoginCookie方法。这个类除在浏览器存储一个名为remember-me的cookie外,还会将series,token值存储到实际的数据库中。cookie字符串数组的数量应为2,分别是series,token。根据series调用tokenRepository.getTokenForSeries方法,比较token,如果匹配则调用UserDetailService.loadUserByUsername方法返回UserDetails对象,否则删除数据库的记录并抛出CookieTheftException。
自己的码云spring-security练习项目,成功接入了GitHub,欢迎访问