Dynamic route configuration in auth success handler

I wanted to configure a dynamic route in an Authentication Sucess Handler for the currently logged in user,
if he is in a certain role. (only for the current user => therefore session scope route). The call of

RouteConfiguration.forSessionScope().setRoute(...)

always failed because there was supposedly no Vaadin session. However, the login view was already displayed beforehand, so a Vaadin session must exist.
The ServiceInitListener in which the creation of the Vaadin session is logged serves as proof.

After activating the display of the current thread in the logback configuration, one can see that the Vaadin session is created in a different thread than the one that handles the login request.
This is IMO a problem. How can I access the Vaadin Session also from this context ?

As a workaround for my original problem, I derived a view from RouteNotFoundError and handled the error there.
However, this only works if there is actually a route-not-found error beforehand, which is the case for me.
It’s not a general solution, as you may also want to define such a dynamic route under other circumstances.

I’ve compiled a Minimal Complete Verifiable Example in https://github.com/to-do42/vaadin-mcve-session and hope somebody from you Vaadin guys can fix my stupid request :slightly_smiling_face:

Hi! The threadlocal for “current” VaadinSession is not set in filters, but by Vaadin Servlet itself. In the VaadinSession JavaDoc’s:
Current VaadinSession object which can be accessed by getCurrent() is not present before VaadinServlet starts handling the HTTP request. For example, it cannot be used in any implementation of Filter interface.

It is bit nasty here, because you are trying to configure available views from a servlet filter.

A workaround: Save the view(s) you want to add to the servlet session and add a requesthandler (SynchronizedRequestHandler) to the Vaadin session where you check if those are added (and add them there).

Hi @quintessential-ibex thank you for your response. I came up with the following solution for my issue:

  1. in the VaadinServiceInitListener.initEvent method I do nothing
  2. I only customize the httpSecurity and create an authSuccessHandler, try to get the Vaadin Session, lock it and do my stuff there. In this case, I have to ensure, that the VaadinAuthSuccessHandler comes also into the play. As long, as the corresponding method is private, I have to copy’n’paste the code, but I’ve created an issue for that.
GrantedAuthority role = userDetails.getAuthorities().stream().findFirst().get();
if (role.getAuthority().equals(Roles.Fields.ZE_TIM_CONTROLLER)) {
    Optional<VaadinSession> vaadinSession = VaadinSession.getAllSessions(request.getSession()).stream().findFirst();
    if (vaadinSession.isPresent()) {
        try {
            vaadinSession.get().lock();
            RouteRegistry sessionRouteRegistry = 
                SessionRouteRegistry.getSessionRegistry(vaadinSession.get());
            RouteConfiguration.forRegistry(sessionRouteRegistry)
                .setRoute("", XYZView.class, MainLayout.class);
        } catch(Exception ex) {
            log.error("Fehler bei der dyn. Routen Definition", ex);
        } finally {
            vaadinSession.get().unlock();
        }
    }
}
// method content copied from parent class ... is private there :-(
getVaadinSavedRequestAwareAuthenticationSuccessHandler(http).onAuthenticationSuccess(request, response, authentication);

For private method accessor I made an issue https://github.com/vaadin/flow/issues/18071