How to set defaultSuccessUrl for formLogin?

Wow, guys, I am having a helluva time today trying to figure this out. This should forward successful logins to my custom url, correct? Well, it never does.

@EnableWebSecurity
@Configuration
@Import(VaadinAwareSecurityContextHolderStrategyConfiguration.class)
public class SecurityConfiguration {

    @Value("${jwt.auth.secret}")
    private String authSecret;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authorize -> {
            authorize.requestMatchers("/images/*.png").permitAll();
            authorize.requestMatchers("/line-awesome/**").permitAll();
            authorize.requestMatchers("/actuator/health").permitAll();
            authorize.requestMatchers("/api/stripe").permitAll();
            authorize.requestMatchers("/ws-agent/**").permitAll();
            authorize.requestMatchers("/api/agent/login").permitAll();
            authorize.requestMatchers("/api/agent/callback").authenticated();
            authorize.requestMatchers("/api/agent/token").authenticated();
        });

        http.with(VaadinSecurityConfigurer.vaadin(), configurer -> configurer.loginView(LoginView.class));
        http.formLogin(form -> form
//                .successHandler(agentAwareSuccessHandler())
                .defaultSuccessUrl("/api/agent/callback?returnUrl=http://localhost:9090/auth-callback", true)
        );
        http.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.decoder(jwtDecoder())));
        http.csrf(csrf -> csrf.ignoringRequestMatchers("/api/stripe"));

        return http.build();
    }

I also tried this:

@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        http.with(VaadinSecurityConfigurer.vaadin(), configurer -> {
            try {
                configurer.loginView(LoginView.class).configure(http.formLogin(form -> form
                        .defaultSuccessUrl("/api/agent/callback?returnUrl=http://localhost:9090/auth-callback", true)
                ));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        http.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.decoder(jwtDecoder())));
        http.csrf(csrf -> csrf.ignoringRequestMatchers("/api/stripe"));

        return http.build();
    }

Which just fails with:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.web.SecurityFilterChain]: Factory method ‘securityFilterChain’ threw exception with message: Can’t configure requestMatchers after anyRequest

So frustrating!!

TLDR: use force=true as second parameter as workaround (never tested… somebody said on GitHub)

Long version: formLogin was never intended to be used together with Vaadin’s chain + success login handler aren’t implemented. defaultSuccessUrl don't work in SecurityFilterChain · Issue #7944 · vaadin/platform · GitHub

1 Like