Security

This section documents the current Vaadin release line — Vaadin 24 LTS / 25.x, Java 17+, Spring Boot 3 / Jakarta EE 10 — as published at the official Vaadin documentation, which is the reference these pages are written and verified against. No specific patch version is pinned. Flow (server-side Java) is the authoring style used throughout, with Hilla / React shown where it differs; Vaadin 7 and the pre-Flow architecture appear only as migration contrast.

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production, since Vaadin ships major releases roughly twice a year and its ecosystem iterates.

This section’s bibliography lists the reference material consulted while preparing these pages.

Vaadin’s security model layers over Spring Security: one filter chain protects the framework’s endpoints, and per-view annotations decide who may open each route. This page follows the Security documentation. It replaces the Vaadin 7 pattern of checking permissions inside a Navigator ViewChangeListener.

Enabling security

Extend VaadinWebSecurity (or apply the security configurer to an HttpSecurity) and point it at a login view. The base class already permits Vaadin’s internal requests and adds the navigation access control filter:

@EnableWebSecurity
@Configuration
public class SecurityConfig extends VaadinWebSecurity {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(auth ->
                auth.requestMatchers("/images/**", "/api/public/**").permitAll());
        super.configure(http);
        setLoginView(http, LoginView.class);
    }

    @Bean
    UserDetailsService users() {
        return new InMemoryUserDetailsManager(
            User.withUsername("admin").password("{noop}admin").roles("ADMIN").build());
    }
}

Protecting routes

Access is denied by default once security is enabled. Open each view with one annotation; the navigation access control filter enforces it on every navigation, server-side:

Annotation Meaning

@AnonymousAllowed

anyone, logged in or not

@PermitAll

any authenticated user

@RolesAllowed("ADMIN")

users with the listed role(s)

@DenyAll

no one (the default for an unannotated view)

@Route("login")
@AnonymousAllowed
public class LoginView extends VerticalLayout { }

@Route(value = "admin", layout = MainLayout.class)
@RolesAllowed("ADMIN")
public class AdminView extends VerticalLayout { }

Put the annotation on a shared parent layout to cover a whole area at once. For finer control, @RouteScoped services can call AccessAnnotationChecker directly.

Login and logout

LoginForm embeds in a view; LoginOverlay is a full-screen modal. Either posts to Spring Security’s /login; AuthenticationContext handles programmatic login and logout:

@Route("login")
@AnonymousAllowed
public class LoginView extends VerticalLayout implements BeforeEnterObserver {

    private final LoginForm login = new LoginForm();

    public LoginView() {
        login.setAction("login");
        add(login);
    }

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

// elsewhere
authenticationContext.logout();

CSRF and CSP

Vaadin’s own client-server channel carries a per-session CSRF token automatically — no configuration needed. A @RestController you add is protected by Spring Security’s CSRF handling as normal. Set a Content Security Policy through the shell:

public class AppShell implements AppShellConfigurator {
    @Override
    public void configurePage(AppShellSettings settings) {
        settings.addMetaTag("Content-Security-Policy",
                "default-src 'self'; img-src 'self' data:");
    }
}

Hilla endpoints

The same annotations secure Hilla endpoints and their methods (Hilla and React Views); @BrowserCallable classes are @DenyAll until annotated. See Hilla security.

Beyond the basics

  • Sensitive data — server-side setVisible(false) genuinely removes a component from the DOM, so hiding an admin button is safe; but never send data to the browser you would not let that user read. What is CORS? covers cross-origin exposure.

  • SSO — the commercial SSO Kit adds OpenID Connect / SAML single sign-on and back-channel logout on top of this model (SSO Kit).

See also