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

Vaadin登录视图Chrome不保存密码及HTTPS重定向问题求助

Vaadin登录视图问题解决方案

问题1:浏览器不提示保存/自动填充登录密码

浏览器无法识别Vaadin默认生成的登录表单,导致密码保存、自动填充功能失效。

解决方案

手动为登录表单及字段添加标准name属性,帮助浏览器识别为登录表单:

@Route("login")
@PageTitle("Login | My App")
public class LoginView extends VerticalLayout implements BeforeEnterObserver {
    private final LoginForm login = new LoginForm();

    public LoginView() {
        addClassName("login-view");
        setSizeFull();
        setAlignItems(Alignment.CENTER);
        setJustifyContentMode(JustifyContentMode.CENTER);

        login.setAction("login");
        login.setForgotPasswordButtonVisible(false);
        
        // 添加标准表单属性,触发浏览器密码保存逻辑
        login.getElement().setAttribute("name", "login-form");
        login.getUsernameField().getElement().setAttribute("name", "username");
        login.getPasswordField().getElement().setAttribute("name", "password");

        add(new H1("My App"), login);
    }

    @Override
    public void beforeEnter(BeforeEnterEvent beforeEnterEvent) {
        if (beforeEnterEvent.getLocation().getQueryParameters().getParameters().containsKey("error")) {
            login.setError(true);
        }
    }
}

同时确保测试环境使用HTTPS(需配置有效证书),浏览器仅在安全连接下触发密码保存提示。

问题2:HTTPS重定向导致密码功能异常

当前重定向配置强制所有请求走HTTPS,登录请求的重定向流程破坏了浏览器的密码保存上下文。

解决方案

修改重定向配置,排除登录路径,避免登录请求被重复重定向:

@Configuration
public class HttpsConfiguration {

    @Autowired
    private Environment environment;

    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint securityConstraint = new SecurityConstraint();
                securityConstraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                // 包含所有路径,但排除登录相关请求
                collection.addPattern("/*");
                collection.addExcludedPattern("/login");
                collection.addExcludedPattern("/login/*");
                securityConstraint.addCollection(collection);
                context.addConstraint(securityConstraint);
            }
        };
        tomcat.addAdditionalTomcatConnectors(redirectConnector());
        return tomcat;
    }

    private Connector redirectConnector() {
        Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
        connector.setScheme("http");
        connector.setPort(Integer.parseInt(environment.getProperty("server.http.port")));
        connector.setSecure(false);
        connector.setRedirectPort(Integer.parseInt(environment.getProperty("server.port")));
        return connector;
    }
}

问题3:setLoginView方法过时的替代方案

VaadinWebSecurityConfigurerAdapter中的setLoginView已过时,改用Spring Security标准的formLogin配置:

修改SecurityConfiguration类

@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends VaadinWebSecurityConfigurerAdapter {

    // ... 原有依赖注入及Bean定义

    public static final String LOGOUT_URL = "/";

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().ignoringRequestMatchers(requestUtil::isFrameworkInternalRequest);
        http.csrf().ignoringRequestMatchers(requestUtil::isEndpointRequest);

        http.requestCache().requestCache(vaadinDefaultRequestCache);

        http.authorizeRequests().antMatchers("/api/**").permitAll();

        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry urlRegistry = http
                .authorizeRequests();

        urlRegistry.requestMatchers(requestUtil::isFrameworkInternalRequest).permitAll();
        urlRegistry.requestMatchers(requestUtil::isAnonymousEndpoint).permitAll();
        urlRegistry.requestMatchers(requestUtil::isAnonymousRoute).permitAll();
        urlRegistry.requestMatchers(getDefaultHttpSecurityPermitMatcher()).permitAll();

        urlRegistry.anyRequest().authenticated();

        viewAccessChecker.enable();

        // 替代过时的setLoginView
        http.formLogin()
                .loginPage("/login") // 指定登录视图路径
                .loginProcessingUrl("/login") // 表单提交处理路径
                .defaultSuccessUrl("/", true) // 登录成功后跳转首页
                .failureUrl("/login?error"); // 登录失败跳转回登录页并携带错误参数

        // 配置登出逻辑
        http.logout()
                .logoutUrl(LOGOUT_URL)
                .logoutSuccessUrl("/login");
    }

    // ... 原有configure(AuthenticationManagerBuilder)及configure(WebSecurity)方法
}

内容的提问来源于stack exchange,提问作者Süniür

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 08:01:58