Redirect after successful login

I have this configuration:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    return http.with(VaadinSecurityConfigurer.vaadin(), configurer -> {
        configurer.loginView(LoginView.class);
    }).build();
}

And this login view:

@Route(value = "/login", autoLayout = false)
@AnonymousAllowed
public class LoginView extends Main implements BeforeEnterObserver {

    private LoginForm login;

    @Override
    protected void onAttach(AttachEvent attachEvent) {
        super.onAttach(attachEvent);
        addClassNames(
                LumoUtility.Display.FLEX,
                LumoUtility.JustifyContent.CENTER,
                LumoUtility.AlignItems.CENTER
        );
        setSizeFull();
        login = new LoginForm();
        login.setForgotPasswordButtonVisible(false);
        login.setAction("login");
        login.addLoginListener(event -> UI.getCurrent().navigate(MainView.class));

        add(login);
    }

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

It works correctly and as expected, however, I get a warning: Using the action attribute together with login listeners is discouraged.

What is the best way to configure redirection after a successful login?

The LoginEvent is meant to perform actions when the credentials are submitted, so when your listener is called, the user might not yet have been authenticated. The login listener is usually used to perform authentication programmatically, not to handle post-authentication actions.

When using Spring Security, if you want to always redirect to a given page after login, you should use the FormLoginConfigurer in your configuration class and remove the login listener in the Vaadin view.

For example

http.formLogin(cfg ->  cfg.successForwardUrl("/"))

or you can use a custom successHandler

By default, Vaadin defines a successHandler implementation that redirects to the protected URL that the user was trying to access or to the root path (/)

Are you sure it works? I remember this discussion defaultSuccessUrl don't work in SecurityFilterChain · Issue #7944 · vaadin/platform · GitHub (which was never moved to flow :sweat_smile:)

Nevertheless: I would expect Vaadin’s configurer to provide such hooks… it feels really weird to configure Vaadin and afterwards add a “form based authentication” just for the handlers

1 Like

@knoobie you’re right! I completely missed that issue.
And, yeah, it’s also weird that we have loginView methods that take a logoutSuccessUrl but not a loginSuccessUrl.
loginSuccessUrl should definitely be added to VaadinSecurityConfigurer.

The current workaround is to register a custom VaadinSavedRequestAwareAuthenticationSuccessHandler

        VaadinSavedRequestAwareAuthenticationSuccessHandler successHandler = new VaadinSavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setDefaultTargetUrl("/main");
        successHandler.setAlwaysUseDefaultTargetUrl(true);
        http.setSharedObject(VaadinSavedRequestAwareAuthenticationSuccessHandler.class, successHandler);

    http.with(vaadin(), c -> { ... });
1 Like