Spring上下文环境下Vaadin CustomAuthenticationFailureHandler失效问题求助
解决方案
问题根源
你当前的配置同时使用了VaadinWebSecurity的setLoginView和手动配置的formLogin,两者存在冲突,导致Spring管理的CustomAuthenticationFailureHandler无法被正确加载生效;另外同时配置failureHandler和failureUrl也会引发逻辑冲突。
修复步骤
1. 调整SecurityConfig配置
移除手动的formLogin完整配置,保留VaadinWebSecurity的原生登录规则,仅通过Spring Security注册自定义失败处理器:
@EnableWebSecurity @Configuration public class SecurityConfig extends VaadinWebSecurity { private final AppUserRepository userRepository; private final CustomAuthenticationFailureHandler failureHandler; public SecurityConfig(AppUserRepository appUserRepository, CustomAuthenticationFailureHandler failureHandler) { this.userRepository = appUserRepository; this.failureHandler = failureHandler; } @Override protected void configure(HttpSecurity http) throws Exception { // 静态资源放行配置 http.authorizeHttpRequests(auth -> auth.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/images/*.png")).permitAll() ); // 仅配置登录失败处理器,不覆盖Vaadin的登录页面规则 http.formLogin(form -> form.failureHandler(failureHandler)); // 其他配置保持不变 http.logout(logout -> logout.permitAll()) .exceptionHandling(e -> e.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))) .headers(headers -> headers.frameOptions(frame -> frame.disable())); // 必须最后调用父类配置,确保Vaadin安全规则生效 super.configure(http); setLoginView(http, LoginView.class); } }
2. 优化CustomAuthenticationFailureHandler的注入方式
保持@Service注解标记,改用构造器注入替代字段注入(更符合Spring最佳实践,避免上下文初始化依赖问题):
@Service @Slf4j public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { private final LogService logService; // 构造器注入LogService public CustomAuthenticationFailureHandler(LogService logService) { this.logService = logService; } @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { String username = request.getParameter("username"); log.error("Wrong login: {}", username); logService.auditLog("UNKNOWN", LogTypes.SEC_ERR, "Wrong login: " + username); // 调用父类方法,确保默认的失败跳转逻辑正常执行 super.onAuthenticationFailure(request, response, exception); } }
3. 验证登录视图的错误展示逻辑
确保Vaadin的LoginView能正确识别登录失败的参数并展示错误:
@Route("login") public class LoginView extends LoginOverlay { public LoginView() { setAction("login"); setTitle("My App"); setDescription("Please log in to continue"); // 检查URL中的error参数,触发错误提示 if (VaadinRequest.getCurrent().getParameter("error") != null) { setError(true); } } }
关键注意事项
- 不要同时使用VaadinWebSecurity的
setLoginView和手动formLogin().loginPage(),二者配置会冲突,导致自定义处理器无法触发。 - 确保
LogService本身是Spring管理的Bean(如标记@Service或@Repository),否则会出现注入失败。
内容的提问来源于stack exchange,提问作者Ferenc Vilagi
相关产品推荐
相关产品推荐

