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

如何用Spring Boot 3.x.x+Vaadin 24实现LDAP登录并替换Controller

Spring Boot 3 + Vaadin 24 实现LDAP登录(Vaadin组件替换Controller)

1. 调整Spring Security配置

首先修改WebSecurityConfig,继承Vaadin官方提供的VaadinWebSecurity类,适配Vaadin路由规则,同时保留LDAP认证逻辑:

package com.example.ldap_demo;

import com.vaadin.flow.spring.security.VaadinWebSecurity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
public class WebSecurityConfig extends VaadinWebSecurity {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 允许匿名访问根路径的主视图(用于触发登录弹窗)
        http.authorizeHttpRequests(auth -> auth
                .requestMatchers("/").permitAll()
                .anyRequest().authenticated()
        );
        // 禁用Spring Security默认表单登录,改用自定义Vaadin弹窗
        http.formLogin().disable();
        // 委托Vaadin处理CSRF、资源访问等安全逻辑
        super.configure(http);
        // 指定登录成功后的跳转视图
        setLoginView(MainView.class);
    }

    @Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .ldapAuthentication()
                .userDnPatterns("uid={0},ou=people")
                .groupSearchBase("ou=groups")
                .contextSource()
                .url("ldap://localhost:8389/dc=springframework,dc=org")
                .and()
                .passwordCompare()
                .passwordEncoder(new BCryptPasswordEncoder())
                .passwordAttribute("userPassword");
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

2. 自定义LDAP登录弹窗组件

创建Vaadin Dialog组件,包含登录表单和认证逻辑:

package com.example.ldap_demo;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.textfield.PasswordField;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

@Component
public class LoginDialog extends Dialog {

    private final AuthenticationManager authenticationManager;

    public LoginDialog(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;

        // 弹窗结构
        H3 title = new H3("LDAP登录");
        TextField usernameField = new TextField("用户名");
        usernameField.setRequired(true);
        PasswordField passwordField = new PasswordField("密码");
        passwordField.setRequired(true);

        // 登录按钮逻辑
        Button loginBtn = new Button("登录", event -> {
            String username = usernameField.getValue();
            String password = passwordField.getValue();

            try {
                // 调用Spring Security执行LDAP认证
                Authentication auth = authenticationManager.authenticate(
                        new UsernamePasswordAuthenticationToken(username, password)
                );
                // 将认证信息存入安全上下文
                SecurityContextHolder.getContext().setAuthentication(auth);
                close();
                Notification.show("登录成功!", 3000, Notification.Position.TOP_CENTER);
            } catch (Exception e) {
                Notification.show("登录失败:" + e.getMessage(), 3000, Notification.Position.TOP_CENTER);
            }
        });

        Button cancelBtn = new Button("取消", event -> close());

        VerticalLayout layout = new VerticalLayout(title, usernameField, passwordField, loginBtn, cancelBtn);
        layout.setSpacing(true);
        layout.setPadding(true);
        add(layout);

        setModal(true);
        setCloseOnOutsideClick(false);
    }
}

3. 创建Vaadin主视图(替换原Controller)

用Vaadin视图替代RestController,提供登录按钮和用户状态查看功能:

package com.example.ldap_demo;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

@Route("") // 设置为根路径
public class MainView extends VerticalLayout {

    public MainView(LoginDialog loginDialog) {
        H1 title = new H1("Vaadin LDAP登录演示");
        
        // 触发登录弹窗的按钮
        Button loginBtn = new Button("点击登录", event -> loginDialog.open());
        
        // 查看当前登录用户的按钮
        Button userInfoBtn = new Button("查看当前用户", event -> {
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            if (auth != null && auth.isAuthenticated() && !"anonymousUser".equals(auth.getName())) {
                Notification.show("当前用户:" + auth.getName(), 3000, Notification.Position.TOP_CENTER);
            } else {
                Notification.show("未登录", 3000, Notification.Position.TOP_CENTER);
            }
        });

        setAlignItems(Alignment.CENTER);
        setJustifyContentMode(JustifyContentMode.CENTER);
        setSizeFull();
        add(title, loginBtn, userInfoBtn);
    }
}

4. 依赖检查

确保pom.xml中包含以下核心依赖:

<!-- Vaadin Spring Boot Starter -->
<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>vaadin-spring-boot-starter</artifactId>
    <version>24.3.0</version>
</dependency>
<!-- Spring Security 及 LDAP 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-ldap</artifactId>
</dependency>

内容的提问来源于stack exchange,提问作者Mansi Adroja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 07:15:56