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

Vaadin8+SpringBoot集成SpringSecurity配置技术咨询

Hey there, I’ve tackled this exact setup before—Vaadin 8 + Spring Boot + Spring Security with pure annotation-based config is totally feasible, no XML, no vaadin4Spring, no external login.html or Spring MVC login pages required. Let’s walk through the step-by-step implementation:


Step 1: Project Dependencies

First, lock in compatible versions—Vaadin 8 works best with Spring Boot 2.3.x (newer versions have compatibility gaps). Here’s the Maven setup:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.12.RELEASE</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-spring-boot-starter</artifactId>
        <version>8.14.3</version> <!-- Latest stable Vaadin 8 release -->
    </dependency>
</dependencies>
Step 2: Spring Security Configuration

This class handles all security rules, login/logout flow, and permission controls—no XML needed:

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.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // Example in-memory users—replace with your custom UserDetailsService for production
        auth.inMemoryAuthentication()
                .passwordEncoder(new BCryptPasswordEncoder())
                .withUser("user")
                .password(new BCryptPasswordEncoder().encode("password"))
                .roles("USER")
                .and()
                .withUser("admin")
                .password(new BCryptPasswordEncoder().encode("admin"))
                .roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                // Disable Spring Security CSRF—Vaadin manages its own CSRF tokens internally
                .csrf().disable()
                // Define access rules
                .authorizeRequests()
                    // Allow Vaadin static resources and login page without authentication
                    .antMatchers("/VAADIN/**", "/login", "/login/**").permitAll()
                    // All other requests require authentication
                    .anyRequest().authenticated()
                .and()
                // Configure form login to use our Vaadin LoginUI
                .formLogin()
                    .loginPage("/login")
                    // Spring Security handles authentication at this endpoint
                    .loginProcessingUrl("/perform_login")
                    // Redirect to MainUI after successful login
                    .defaultSuccessUrl("/", true)
                    .permitAll()
                .and()
                // Configure logout flow
                .logout()
                    .logoutUrl("/logout")
                    .logoutSuccessUrl("/login?logout")
                    .permitAll();
    }
}
Step 3: Vaadin Login UI

This is your /login path UI, built entirely with Vaadin components—no external HTML:

import com.vaadin.annotations.Theme;
import com.vaadin.annotations.Title;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.*;
import com.vaadin.ui.themes.ValoTheme;

@SpringUI(path = "/login")
@Theme("valo")
@Title("Application Login")
public class LoginUI extends UI {

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        VerticalLayout layout = new VerticalLayout();
        layout.setSizeFull();
        layout.setMargin(true);
        layout.setSpacing(true);
        layout.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);

        // Login form
        FormLayout formLayout = new FormLayout();
        formLayout.setSpacing(true);

        TextField usernameField = new TextField("Username");
        usernameField.setWidth("300px");
        usernameField.setRequiredIndicatorVisible(true);
        usernameField.setId("username"); // Matches Spring Security's default parameter name

        PasswordField passwordField = new PasswordField("Password");
        passwordField.setWidth("300px");
        passwordField.setRequiredIndicatorVisible(true);
        passwordField.setId("password"); // Matches Spring Security's default parameter name

        Button loginButton = new Button("Login");
        loginButton.setWidth("100%");
        loginButton.addStyleName(ValoTheme.BUTTON_PRIMARY);

        // Handle login button click
        loginButton.addClickListener(event -> {
            if (usernameField.isEmpty() || passwordField.isEmpty()) {
                Notification.show("Please fill all fields", Notification.Type.WARNING_MESSAGE);
                return;
            }
            // Submit credentials to Spring Security's authentication endpoint
            getPage().setLocation("/perform_login?username=" + usernameField.getValue() + "&password=" + passwordField.getValue());
        });

        formLayout.addComponents(usernameField, passwordField, loginButton);
        layout.addComponent(formLayout);

        // Show logout success message if coming from logout
        if (vaadinRequest.getParameter("logout") != null) {
            Notification.show("You've been logged out successfully", Notification.Type.HUMANIZED_MESSAGE);
        }

        setContent(layout);
    }
}
Step 4: Main UI with Spring Views

This is your root path UI, with a SpringNavigator to manage multiple @SpringView components:

import com.vaadin.annotations.Theme;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.spring.navigator.SpringNavigator;
import com.vaadin.ui.*;
import org.springframework.beans.factory.annotation.Autowired;

@SpringUI(path = "")
@Theme("valo")
public class MainUI extends UI {

    private final SpringNavigator navigator;

    @Autowired
    public MainUI(SpringNavigator navigator) {
        this.navigator = navigator;
    }

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        VerticalLayout mainLayout = new VerticalLayout();
        mainLayout.setSizeFull();
        mainLayout.setMargin(false);
        mainLayout.setSpacing(false);

        // Header with logout button
        HorizontalLayout header = new HorizontalLayout();
        header.setWidth("100%");
        header.setPadding(true);
        header.addComponent(new Label("My Vaadin 8 App"));
        
        Button logoutBtn = new Button("Logout");
        logoutBtn.addClickListener(event -> getPage().setLocation("/logout"));
        header.addComponent(logoutBtn);
        header.setComponentAlignment(logoutBtn, Alignment.MIDDLE_RIGHT);
        header.setExpandRatio(header.getComponent(0), 1);

        // View display container
        Panel viewPanel = new Panel();
        viewPanel.setSizeFull();

        mainLayout.addComponents(header, viewPanel);
        mainLayout.setExpandRatio(viewPanel, 1);

        setContent(mainLayout);

        // Initialize navigator to manage views in the panel
        navigator.init(this, viewPanel);
    }
}

Example Spring Views

Just annotate your views with @SpringView—they’ll auto-register with the navigator:

import com.vaadin.spring.annotation.SpringView;
import com.vaadin.ui.Label;
import com.vaadin.ui.VerticalLayout;

@SpringView(name = DashboardView.VIEW_NAME)
public class DashboardView extends VerticalLayout {
    public static final String VIEW_NAME = "dashboard";

    public DashboardView() {
        addComponent(new Label("Welcome to the Dashboard!"));
        setSizeFull();
        setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
    }
}
import com.vaadin.spring.annotation.SpringView;
import com.vaadin.ui.Label;
import com.vaadin.ui.VerticalLayout;

@SpringView(name = ProfileView.VIEW_NAME)
public class ProfileView extends VerticalLayout {
    public static final String VIEW_NAME = "profile";

    public ProfileView() {
        addComponent(new Label("Your Profile Details"));
        setSizeFull();
        setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
    }
}

Key Notes to Avoid Issues
  • Version Compatibility: Stick to Spring Boot 2.3.x with Vaadin 8—newer Spring Boot versions break Vaadin 8’s Spring integration.
  • CSRF Safety: We disable Spring Security’s CSRF because Vaadin handles its own CSRF tokens, so you’re not sacrificing security.
  • View Access: Once a user is authenticated, they can access all @SpringView components in MainUI—add method-level security with @PreAuthorize if you need granular control.

内容的提问来源于stack exchange,提问作者David B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:25:09