> Markdown version of [Add Login](https://vaadin.com/docs/latest/building-apps/security/add-login). Section index: [llms.txt](https://vaadin.com/docs/latest/building-apps/llms.txt)

# Add Login

Most enterprise applications require users to authenticate before accessing the application. Vaadin applications use **Spring Security** for all security features, including authentication. Any authentication method available in Spring Security can also be used in a Vaadin application.

This guide shows you how to set up **in-memory authentication** for development and testing purposes.

> **Warning: Never Use Hard-Coded Credentials In Production**
>
> In-memory authentication is convenient for development, but production applications must use a more secure approach, such as **JDBC authentication**, **LDAP authentication**, or **OAuth 2.0**. Refer to the [Spring Security Reference Manual](https://docs.spring.io/spring-security/reference/servlet/authentication/index.html) for more details.

## <a id="steps-to-set-up-authentication"></a>Steps to Set Up Authentication

To enable authentication in a Vaadin application, follow these steps:

1. Add the **Spring Security dependency** to your project.

2. Create a **Spring Security configuration class**.

3. Create a **login view**.

4. Grant access to specific views and layouts.

This guide covers the first three steps. For the fourth step, see the [Protect Views](https://vaadin.com/docs/latest/building-apps/security/protect-views.md) guide.

## <a id="add-spring-security-dependency"></a>Add Spring Security Dependency

Since Vaadin applications are built on Spring Boot, adding the **Spring Security starter** dependency enables authentication:

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
```

## <a id="create-a-security-configuration-class"></a>Create a Security Configuration Class

Simply adding Spring Security to your project locks you out of your application unless you configure authentication. You must define a `UserDetailsService` and a login form to allow users to log in.

> **Tip: Security Package**
>
> It’s best practice to create a dedicated package for security-related classes. If your root package is `com.example.application`, place the security configuration inside: `com.example.application.security`

This is a minimal implementation of a security configuration class:

`SecurityConfig.java`

```java
@EnableWebSecurity
@Configuration
class SecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // Configure Vaadin's security using VaadinSecurityConfigurer
        http.with(VaadinSecurityConfigurer.vaadin(), configurer -> { // (1)
            // TODO Configure the login view
        });
        return http.build();
    }

    @Bean
    public UserDetailsManager userDetailsManager() {
        LoggerFactory.getLogger(SecurityConfig.class)
            .warn("NOT FOR PRODUCTION: Using in-memory user details manager!"); // (2)
        var user = User.withUsername("user")
                .password("{noop}user")
                .roles("USER")
                .build();
        var admin = User.withUsername("admin")
                .password("{noop}admin")
                .roles("ADMIN")
                .build();
        return new InMemoryUserDetailsManager(user, admin);
    }
}
```

1. Always call with `VaadinSecurityConfigurer.vaadin()` — this ensures that the application is properly configured.

2. **Tip:** Log a warning message whenever using a configuration that shouldn’t end up in production.

The `VaadinSecurityConfigurer` class provides essential security configurations out of the box, including:

- CSRF protection

- Default request caching

- Access restriction to Vaadin views and services

> **Note:** To customize security rules—such as allowing anonymous access to static resources, adjust the configuration of `securityFilterChain` for `VaadinSecurityConfigurer`. It applies a **catch-all rule** denying access for *all* requests, but this rule can be customized or disabled (passing `null`) via `VaadinSecurityConfigurer.anyRequest(…​)`.

## <a id="create-a-login-view"></a>Create a Login View

The login view is a standard [Vaadin view](https://vaadin.com/docs/latest/building-apps/views/add-view.md). The easiest way to implement one is by using the [LoginForm](https://vaadin.com/docs/latest/components/login.md) component:

LoginView\.java

```java
@Route(value = "login", autoLayout = false) // (1)
@PageTitle("Login")
@AnonymousAllowed // (2)
public class LoginView extends Main implements BeforeEnterObserver {

    private final LoginForm login;

    public LoginView() {
        login = new LoginForm();
        login.setAction("login"); // (3)

        VerticalLayout layout = new VerticalLayout();
        layout.setAlignItems(FlexComponent.Alignment.CENTER);
        layout.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
        layout.add(login);
        layout.setSizeFull();

        add(layout);
        setSizeFull();
    }

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

1. Disables auto layout to prevent the login view from being embedded in a [router layout](https://vaadin.com/docs/latest/building-apps/views/add-router-layout.md).

2. Allows anonymous access so users can access the login page without authentication.

3. Instructs the login form to send a `POST` request to `/login` for authentication.

4. Handles login failures by checking for the `?error` query parameter and displaying an error message.

Spring Security’s **form login** mechanism automatically processes authentication requests sent to `/login`. When authentication fails, the user is redirected back to the login page with `?error`, which the login view handles.

## <a id="configuration"></a>Configuration

To instruct Spring Security to use your login view, modify your security configuration:

`SecurityConfig.java`

```java
@EnableWebSecurity
@Configuration
class SecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // Configure Vaadin's security using VaadinSecurityConfigurer
        http.with(VaadinSecurityConfigurer.vaadin(), configurer -> {
// tag::snippet[]
            configurer.loginView(LoginView.class);
// end::snippet[]
        });

        return http.build();
    }
    ...
}
```

Now, when a user tries to access the application, they’ll be redirected to the login page.

> **Note: Post-Login Redirect**
>
> After a successful login, Spring Security redirects the user to the originally requested URL. If no specific URL was requested (for example, the user navigated directly to the login page), Spring Security redirects to `/`. Make sure a view is mapped to the root route (`@Route("")`), or configure a default redirect. Without a root route, users see a 404 or blank page after login.

> **Important: Access Denied by Default**
>
> By default, Vaadin **restricts access to server-side views and router layouts**. Unless explicitly permitted, even authenticated users will be unable to access views. This is covered in more detail in the [Protect Views](https://vaadin.com/docs/latest/building-apps/security/protect-views.md) guide. React views work the other way around: a React view is public unless it requires login. See [Secure React Views](https://vaadin.com/docs/latest/building-apps/react/security.md#requiring-authentication).
