Correct way to login a user programmatically to a Vaadin App on Spring Boot Security?

My use case is a registration form that also logs in the newly registered user on Vaadin v.24 and Spring Boot 3. I tried using basic examples from SO and GH such as

  final String email = registrationVO.getEmail();
  final String password = registrationVO.getPassword();
  final Authentication request = new UsernamePasswordAuthenticationToken(email, password);
  final Authentication result = authenticationManager.authenticate(request);
  SecurityContextHolder.getContext().setAuthentication(result);

but it doesn’t work because

  final Optional<UserDetails> authenticatedUser = authenticationContext.getAuthenticatedUser(UserDetails.class);

is empty. I tried walk through the Vaadin security and Spring code and my only guess is that VaadinSession is not getting created using the basic example above.

authenticationContext is com.vaadin.flow.spring.security.AuthenticationContext.

I’d appreciate help because Googling and debuggin didn’t help.

What does getAuthenticatedUser do?

/**
* Gets an {@link Optional} with an instance of the current user if it has
* been authenticated, or empty if the user is not authenticated.
*
* Anonymous users are considered not authenticated.
*
* @param
* the type parameter of the expected user instance
* @param userType
* the type of the expected user instance
* @return an {@link Optional} with the current authenticated user, or empty
* if none available
* @throws ClassCastException
* if the current user instance does not match the given
* {@code userType}.
*/

com.vaadin.flow.spring.security.AuthenticationContext.getAuthenticatedUser(). It’s the way Vaadin suggests getting an authenticated user when using Vaadin Spring Security.

If you have walked through the code - what instance is within the getAuthenticatedUser? Because of the UserDetails.class param you limiting the possible return types.

And your authenticationManager is legit and does what it has to do?

UserDetails is an extension of Spring’s UserDetails.

AuthenticationManager is injected as org.springframework.security.authentication.AuthenticationManager. The implementation is ProviderManager that delegates to Spring’s DaoProvider.

To add more context, if I use LoginForm, final Optional authenticatedUser = authenticationContext.getAuthenticatedUser(UserDetails.class); works fine.

If I use “programmatic” login, getAuthenticateUser returns empty.

If I understadn the code, using /login creates VaadinSession, that Vaadin’s AuthenticationContext.getAuthenticatedUser() uses to return the principal. “programmatic” approach doesn’t seem to do it.

Sounds like your programming has the error. You have to debug why it’s not authenticated. Keep in mind that your token also provided a setAuthenticated method if your delegate doesn’t what you think it does. Hard for use to help you here.

Can you please show the code of your AuthenticationManager?

@adaptable-uakari , maybe I’m asking the question a wrong way. What’s the best way to build a “Register” view that allows to log in a user in a single go in Vaadin Spring Security context?

Your way looks good but as Knoobie said the returned value seems incorrect

@observant-quetzal it’s not Vaadin but Spring Secuity and your question should be how to manualy login user

spring security is returning a session based value when you reigster the client, you need to pass it to Vaadin Session

@charming-frog , yes, this is the question of how to log in a user manaully. I just cannot figure out how.

@observant-quetzal I sorry my friend, I was sure i have wrote the answer, forgot to hit enter.

@Route(“login”)
@PageTitle(“Login”)
@AnonymousAllowed
public class LoginView extends VerticalLayout {

@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
private LoginForm login = new LoginForm();

private final SecurityContextRepository securityContextRepository =
        new HttpSessionSecurityContextRepository();

public LoginView() {
    addClassName("login-view");
    setSizeFull();

    setJustifyContentMode(JustifyContentMode.CENTER);
    setAlignItems(Alignment.CENTER);

    login.addLoginListener((e)-> {

        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));

        Authentication authentication
                = new UsernamePasswordAuthenticationToken(e.getUsername(), e.getPassword(), authorities);
        VaadinAwareSecurityContextHolderStrategy strategy = new VaadinAwareSecurityContextHolderStrategy();

        SecurityContext context = strategy.createEmptyContext();
        context.setAuthentication(authentication);
        strategy.setContext(context);
        securityContextRepository.saveContext(context, request, response);

        UI.getCurrent().navigate(MainView.class);
    });

    add(new H1("Test Application"), login);
}

}