Does BeforeEnterEvent execute before target view instantiation?
0 reputation · 05 Apr 2024, 20:43 UTC
0 reputation · 05 Apr 2024, 20:43 UTC
Vaadin applications utilize a route-based navigation system where views annotated with @Route are accessible by default. To prevent accidental public access, developers typically integrate Spring Security or use the BeforeEnterEvent to intercept navigation and verify authentication before the target view is rendered.
There is a concern regarding the precise sequence of the navigation lifecycle. Specifically, it is unclear if the framework instantiates the target view component before the BeforeEnterEvent logic is fully processed. If the view is instantiated prior to the access check, it could lead to unnecessary resource allocation or the execution of constructor logic for unauthorized users.
Which phase of the navigation lifecycle triggers the instantiation of the view class relative to the BeforeEnterEvent? Does this behavior vary when using @PermitAll versus manual programmatic checks?
32275 reputation · 06 Apr 2024, 04:28 UTC
Yes. In Vaadin Flow 14 and later, the router dispatches BeforeEnterEvent before the view provider creates an instance of the destination view class.
The default router sequence is:
BeforeEnterEvent is fired to registered BeforeEnterListener instances.event.forwardTo() or event.rerouteTo(), navigation is aborted and the original view constructor never runs.AfterEnterEvent is then fired.Because the event precedes instantiation, constructor logic in the target view does not execute for unauthorized users when a listener reroutes. This makes the event suitable for guarding expensive view setup, though field injection and initialization still occur only after the view is created.
@PermitAll change this?No. Spring Security annotations such as @PermitAll operate outside the Vaadin router lifecycle. They affect authorization decisions in the security layer, but they do not move view instantiation earlier in the Vaadin navigation sequence. The router still fires BeforeEnterEvent before creating the view.
The order described above applies to the default ViewProvider implementations. If you supply a custom provider that instantiates the view before the event is dispatched, the observed order can differ. With standard configuration, however, the event always comes first.
You can confirm the order with a temporary log in the view constructor and a global listener:
@Route("protected")
public class ProtectedView extends VerticalLayout {
public ProtectedView() {
System.out.println("View constructed");
}
}
public class AuthListener implements BeforeEnterListener {
@Override
public void beforeEnter(BeforeEnterEvent event) {
System.out.println("BeforeEnter received");
if (!isAuthenticated()) {
event.rerouteTo("login");
}
}
}
When navigation proceeds, "BeforeEnter received" prints before "View constructed". When the listener reroutes, the constructor log is absent.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.