Docs

Custom Error Views

The security configuration that custom error views need in a Spring Security application.

Access-Denied & Not-Found Views describes how to create custom error views for routes that don’t exist or that the user can’t access. With Spring Security, a custom not-found view also needs additional security configuration to be reachable for users.

Custom Not-Found View

In an application secured with VaadinSecurityConfigurer, the not-found view also needs a relaxed catch-all request rule, so that requests for non-existing pages reach the Vaadin servlet. By default, VaadinSecurityConfigurer denies every request that isn’t explicitly allowed. A URL that doesn’t match any route, entered in the browser’s address bar or opened from a bookmark, is therefore denied by Spring Security before Vaadin can show the not-found view. The access annotation on the view doesn’t change this, as it’s checked only after the request reaches the Vaadin servlet.

The security configuration then relaxes the catch-all rule with anyRequest():

Source code
SecurityConfiguration.java
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.with(VaadinSecurityConfigurer.vaadin(), configurer -> {
        configurer.loginView(LoginView.class)
                .anyRequest(AuthorizedUrl::permitAll); 1
    });
    return http.build();
}
  1. Lets requests that match no other rule reach the Vaadin servlet, which shows the not-found view for them.

This doesn’t expose your views: they’re still protected at the HTTP layer by the request matchers of VaadinSecurityConfigurer, and by navigation access control. However, the catch-all rule also covers every other endpoint of the application, such as REST controllers or Spring Boot Actuator endpoints. Protect those with rules of their own before relaxing the catch-all rule, as rules added to http before the configurer are applied first.

If only signed-in users need to see the not-found view, use AuthorizedUrl::authenticated instead of AuthorizedUrl::permitAll. Users who aren’t signed in are then sent to the log-in view for any unknown URL, and other unmatched endpoints require authentication. See Security Configuration for the other options of anyRequest(), and Handle Errors for a guide to the error views of an application.

Updated –