You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vaadin 24整合Spring Security配置时出现无效JSON响应及路由导航异常

Vaadin 24整合Spring Security配置时出现无效JSON响应及路由导航异常

从你提供的信息和Debug日志来看,问题的核心出在登录请求参数不匹配和Vaadin视图访问控制配置冲突上,我来一步步帮你梳理解决:

一、先解决「Invalid JSON响应」的问题

从日志里的Failed to find user ''可以看出,Spring Security收到了一个空的用户名,导致认证失败后触发了重定向(跳转到/?error),而Vaadin前端此时正在等待JSON格式的UIDL响应,收到HTML重定向内容就会抛出无效JSON的错误。

解决步骤:

  1. 检查你的LoginView表单字段
    确保登录表单的用户名、密码输入框的name属性严格对应Spring Security的默认参数名:username和password。比如:

    @Route("login")
    @AnonymousAllowed // 必须加这个,让未登录用户能访问登录页
    public class LoginView extends VerticalLayout {
        public LoginView() {
            TextField usernameField = new TextField("用户名");
            usernameField.setName("username"); // 关键:name属性不能错
            usernameField.setAutofocus(true);
    
            PasswordField passwordField = new PasswordField("密码");
            passwordField.setName("password"); // 同上
    
            Button loginBtn = new Button("登录", e -> {
                // 用Vaadin的认证机制处理,避免Spring Security的默认重定向
                Authentication auth = UsernamePasswordAuthenticationToken.unauthenticated(
                    usernameField.getValue(), passwordField.getValue()
                );
                try {
                    auth = SecurityContextHolder.getContext().getAuthenticationManager().authenticate(auth);
                    SecurityContextHolder.getContext().setAuthentication(auth);
                    // 登录成功后跳转到主视图
                    UI.getCurrent().navigate(MainView.class);
                } catch (AuthenticationException ex) {
                    Notification.show("登录失败:" + ex.getMessage(), 3000, Notification.Position.TOP_CENTER);
                }
            });
    
            add(usernameField, passwordField, loginBtn);
            setSizeFull();
            setAlignItems(Alignment.CENTER);
            setJustifyContentMode(JustifyContentMode.CENTER);
        }
    }
    
  2. 修正SecurityConfig的登录视图配置
    确保setLoginView指向正确的LoginView,同时提前开放静态资源的访问权限:

    @EnableWebSecurity
    @Configuration
    public class SecurityConfig extends VaadinWebSecurity {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // 先开放Vaadin静态资源,避免被拦截
            http.authorizeHttpRequests()
                    .requestMatchers(new AntPathRequestMatcher("/VAADIN/**"),
                                    new AntPathRequestMatcher("/themes/**"))
                    .permitAll();
    
            super.configure(http);
            // 正确绑定登录视图
            setLoginView(http, LoginView.class);
        }
    
        @Override
        public void configure(WebSecurity web) throws Exception {
            // 让Spring Security忽略Vaadin的内部请求
            web.ignoring().requestMatchers(
                    new AntPathRequestMatcher("/VAADIN/**"),
                    new AntPathRequestMatcher("/themes/**"),
                    new AntPathRequestMatcher("/favicon.ico")
            );
            super.configure(web);
        }
    
        @Bean
        public UserDetailsManager userDetailsService() {
            UserDetails user = User.withUsername("user")
                    .password("{noop}user")
                    .roles("USER")
                    .build();
            UserDetails admin = User.withUsername("admin")
                    .password("{noop}admin")
                    .roles("ADMIN")
                    .build();
            return new InMemoryUserDetailsManager(user, admin);
        }
    }
    

二、解决「路由导航异常」的问题

当你注释掉setLoginView后,Vaadin的视图访问检查器没有正确生效,导致所有路由都被拦截。解决要点:

  1. 给需要授权访问的视图添加权限注解
    比如主视图MainView:

    @Route("main")
    @RolesAllowed({"USER", "ADMIN"}) // 允许普通用户和管理员访问
    public class MainView extends VerticalLayout {
        // ... 视图代码
    }
    

    注册页、登录页这类允许匿名访问的页面,必须添加@AnonymousAllowed注解。

  2. 不要手动覆盖VaadinWebSecurity的核心配置
    VaadinWebSecurity已经帮你处理了CSRF保护、视图访问检查、请求缓存等适配Vaadin的配置,不要手动添加http.formLogin()这类原生Spring Security配置,否则会和Vaadin的机制冲突。

额外注意事项

  • 不要使用Spring Security的默认登录端点(/login),而是用Vaadin自己的LoginView处理登录,避免重定向导致的JSON响应错误。
  • 确保你的Vaadin版本(24.0.3)和Spring Boot版本(3.0.5)兼容,这两个版本的搭配是没问题的,但要注意依赖的一致性。

备注:内容来源于stack exchange,提问作者Jmork

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 10:14:32