如何用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
相关产品推荐
相关产品推荐

