Vaadin 24.3.x + Spring Boot 3.2.4 记住我认证开发求助(旧API已弃用)
Vaadin 24.3.x + Spring Boot 3.2.4 实现Remember-Me认证方案
针对Spring Security中rememberMe()方法弃用的情况,结合Vaadin登录组件,可通过以下步骤实现持久化的Remember-Me功能:
1. 更新Security配置类
注入用户详情服务和数据源,配置基于数据库的令牌存储,用新的lambda配置方式替代弃用方法:
@EnableWebSecurity @Configuration public class SecurityConfiguration extends VaadinWebSecurity { private final UserDetailsService userDetailsService; private final DataSource dataSource; // 构造注入依赖 public SecurityConfiguration(UserDetailsService userDetailsService, DataSource dataSource) { this.userDetailsService = userDetailsService; this.dataSource = dataSource; } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } // 配置数据库令牌存储 @Bean public PersistentTokenRepository persistentTokenRepository() { JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl(); tokenRepository.setDataSource(dataSource); // 首次启动可开启自动建表,生产环境建议手动执行下方SQL // tokenRepository.setCreateTableOnStartup(true); return tokenRepository; } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeHttpRequests( authorize -> authorize.requestMatchers(new AntPathRequestMatcher("/images/*.png")).permitAll()); // 放行line-awesome图标资源 http.authorizeHttpRequests(authorize -> authorize .requestMatchers(new AntPathRequestMatcher("/line-awesome/**/*.svg")).permitAll()); // 配置Remember-Me http.rememberMe(remember -> remember .userDetailsService(userDetailsService) .tokenRepository(persistentTokenRepository()) .tokenValiditySeconds(86400) // 令牌有效期1天 .rememberMeParameter("remember-me") // 与登录表单参数名保持一致 ); super.configure(http); setLoginView(http, LoginView.class); } }
2. 自定义登录视图添加"记住我"复选框
在Vaadin登录视图中添加复选框,并在登录提交时传递remember-me参数:
@Route("login") public class LoginView extends VerticalLayout implements BeforeEnterObserver { private final LoginForm loginForm = new LoginForm(); private final Checkbox rememberMe = new Checkbox("记住我"); public LoginView() { setSizeFull(); setAlignItems(Alignment.CENTER); setJustifyContentMode(JustifyContentMode.CENTER); loginForm.setAction("login"); rememberMe.setValue(false); // 将复选框添加到登录表单的额外区域 loginForm.addExtraHeaderContent(new Div(rememberMe)); // 处理登录提交逻辑 loginForm.addLoginListener(event -> { // 构建未认证的令牌 Authentication authentication = UsernamePasswordAuthenticationToken.unauthenticated( event.getUsername(), event.getPassword()); // 设置请求详情 authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails( VaadinServletRequest.getCurrent().getHttpServletRequest())); // 传递remember-me参数到请求中 VaadinServletRequest.getCurrent().getHttpServletRequest().setParameter( "remember-me", rememberMe.getValue() ? "on" : null); try { // 执行认证 Authentication authenticated = AuthenticationManagerResolver.forHttpServletRequest() .resolve(VaadinServletRequest.getCurrent().getHttpServletRequest()) .authenticate(authentication); SecurityContextHolder.getContext().setAuthentication(authenticated); // 登录成功跳转首页 UI.getCurrent().navigate(""); } catch (AuthenticationException e) { loginForm.setError(true); } }); add(loginForm); } @Override public void beforeEnter(BeforeEnterEvent event) { // 已登录用户直接跳转首页 if (SecurityContextHolder.getContext().getAuthentication() != null && SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) { event.forwardTo(""); } } }
3. 创建数据库令牌存储表(生产环境必做)
若使用数据库存储令牌,需手动创建persistent_logins表,SQL如下:
CREATE TABLE persistent_logins ( username VARCHAR(64) NOT NULL, series VARCHAR(64) PRIMARY KEY, token VARCHAR(64) NOT NULL, last_used TIMESTAMP NOT NULL );
注意事项
- 确保
UserDetailsService已正确实现,能从数据库读取用户信息 - 若无需持久化令牌,可移除
PersistentTokenRepository配置,使用默认内存存储(仅适用于开发环境) - 可根据业务需求调整
tokenValiditySeconds参数,例如7天有效期设为604800
内容的提问来源于stack exchange,提问作者Patrick Lange
相关产品推荐
相关产品推荐

