6.remember me功能
remember me功能
在大多数网站中,都会实现 Remember Me 这个功能,方便用户在下一次登录时直接登录,避免再次输入用户名以及密码去登录,Spring Security针对这个功能已经帮助我们实现,如下图:
Token=MD5(username+分隔符+expiryTime+分隔符+password)
注意: 这种方式不推荐使用, 有严重的安全问题. 就是密码信息在前端浏览器cookie中存放. 如果cookie 被盗取很容易破解.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | @Override protected void configure(HttpSecurity http) throws Exception { /** http.httpBasic() //开启httpBasic认证 .and().authorizeRequests().anyRequest().authenticated(); //所有请求都需要认证之后访问 */ /* http.formLogin().loginPage("/login.html")//开启表单认证 // .and().authorizeRequests() //放行登录页面 // .anyRequest().authenticated(); // .and().authorizeRequests().antMatchers("/login.html").permitAll() //放行登录页面 .and().authorizeRequests().antMatchers("/toLoginPage").permitAll() //放行登录页面 .anyRequest().authenticated();*/ http.formLogin() //开启表单认证 .loginPage( "/toLoginPage" ) // 自定义登陆页面 .loginProcessingUrl( "/login" ) //表单提交路径 .usernameParameter( "username" ).passwordParameter( "password" ) //自定义input额name值和password .successForwardUrl( "/" ) //登录成功之后跳转的路径 .and().authorizeRequests().antMatchers( "/toLoginPage" ).permitAll() //放行登录页面 .anyRequest().authenticated() .and().rememberMe() //开启记住我功能 .tokenValiditySeconds(1209600) //token失效时间,默认失效时间是两周 .rememberMeParameter( "remember-me" ) // 自定义表单name值 .and().headers().frameOptions().sameOrigin() //加载同源域名下iframe页面 .and().csrf().disable(); //关闭csrf防护 } |
login.html
测试如下
上面所说,密码信息也会存放在cookie中,容易被抓取破解,下面我们可以改造一下,基于持久化的Token生成方法,如下图
存入数据库Token包含:
token: 随机生成策略,每次访问都会重新生成
series: 登录序列号,随机生成策略。用户输入用户名和密码登录时,该值重新生成。使用 remember-me功能,该值保持不变
expiryTime: token过期时间
CookieValue=encode(series+token)
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 | @Autowired DataSource dataSource; /** * 负责token与数据库之间的操作 * @return */ @Bean public PersistentTokenRepository getPersistentTokenRepository(){ JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl(); tokenRepository.setDataSource(dataSource); //设置数据源 tokenRepository.setCreateTableOnStartup( true ); //启动时帮助我们自动创建一张表,第一次启动设置为true,第二次启动程序的时候设置false或者注释掉; return tokenRepository; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | @Override protected void configure(HttpSecurity http) throws Exception { /** http.httpBasic() //开启httpBasic认证 .and().authorizeRequests().anyRequest().authenticated(); //所有请求都需要认证之后访问 */ /* http.formLogin().loginPage("/login.html")//开启表单认证 // .and().authorizeRequests() //放行登录页面 // .anyRequest().authenticated(); // .and().authorizeRequests().antMatchers("/login.html").permitAll() //放行登录页面 .and().authorizeRequests().antMatchers("/toLoginPage").permitAll() //放行登录页面 .anyRequest().authenticated();*/ http.formLogin() //开启表单认证 .loginPage( "/toLoginPage" ) // 自定义登陆页面 .loginProcessingUrl( "/login" ) //表单提交路径 .usernameParameter( "username" ).passwordParameter( "password" ) //自定义input额name值和password .successForwardUrl( "/" ) //登录成功之后跳转的路径 .and().authorizeRequests().antMatchers( "/toLoginPage" ).permitAll() //放行登录页面 .anyRequest().authenticated() .and().rememberMe() //开启记住我功能 .tokenValiditySeconds(1209600) //token失效时间,默认失效时间是两周 .rememberMeParameter( "remember-me" ) // 自定义表单name值 .tokenRepository(getPersistentTokenRepository()) //设置PersistentTokenRepository .and().headers().frameOptions().sameOrigin() //加载同源域名下iframe页面 .and().csrf().disable(); //关闭csrf防护 } |
运行后,数据库会生成一张对应的表
登陆成功之后,观察数据库,会插入一条记录.说明持久化token方式已经生效;
cookie窃取伪造登录成功,访问接口获取数据,只需在关键接口处添加如下代码,可解决此问题。如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /** * 根据用户ID查询用户 * * @return */ @GetMapping( "/{id}" ) @ResponseBody public User getById(@PathVariable Integer id) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); //如果返回true,代表这个登录认证的信息来源于自动登录 if (RememberMeAuthenticationToken. class .isAssignableFrom(authentication.getClass())){ throw new RememberMeAuthenticationException( "认证来源于remember me" ); } User user = userService.getById(id); return user; } |
分类:
spring security
标签:
spring security
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY