As documented on https://vaadin.com/docs/latest/security/enabling-security, in a Java Spring Vaadin application, annotations can be used to define if pages should be shown after login based on Roles like this:
@Route(value = "admin", layout = MainView.class)
@PageTitle("Admin View")
@RolesAllowed("ADMIN") // <- Should match one of the user's roles (case-sensitive)
public class AdminView extends VerticalLayout {
// ...
}
Or pages can always be shown with:
@Route(value = "home", layout = MainView.class)
@PageTitle("Homepage")
@AnonymousAllowed // or @PermitAll
public class HomePageView extends VerticalLayout {
// ...
}
But what I'm missing in the documentation, is how a page can be hidden after a user has logged in. Is some kind of "negative" annotation available? E.g.
@Route(value = "register", layout = MainView.class)
@PageTitle("Register as a new user")
@RolesNotAllowed({"ADMIN", "USER"}) // <- This annotation doesn't exist (yet?)
public class RegisterView extends VerticalLayout {
// View only needed for users who didn't login yet
}
---- Update 20220103
One solution is to remove the page from the menu by checking the authenticated user:
Optional<User> maybeUser = authenticatedUser.get();
if (accessChecker.hasAccess(RegisterView.class)
&& !maybeUser.isPresent()) {
nav.addItem(new AppNavItem("Register", RegisterView.class, "la la-user"));
}
But still, the page can be accessed directly via the URL. As suggested by @gidravlic, I tried to remove the page from the route configuration, but it's still accessible. So this is not a "full" solution. This doesn't seem to have any effect:
if (maybeUser.isPresent()) {
RouteConfiguration configuration = RouteConfiguration.forSessionScope();
configuration.removeRoute(RegisterView.class);
}
CodePudding user response:
You can use BeforeEnterObserver
and the BeforeEnterEvent
to forward the user to another view when they're trying to access one that they're not supposed to:
@Route(value = "register", layout = MainView.class)
@PageTitle("Register as a new user")
@AnonymousAllowed
public class RegisterView extends VerticalLayout
implements BeforeEnterObserver {
@Override
public void beforeEnter(BeforeEnterEvent event) {
if (hasLoggedIn()) {
event.forwardTo(SomeOtherView.class);
}
}
private boolean hasLoggedIn() {
Optional<User> maybeUser = authenticatedUser.get();
return maybeUser.isPresent();
}
}
You can update the menu e.g. with the MainView
's AfterNavigationObserver
which works similarly to the BeforeEnterObserver
except it gets triggered after all navigation activities are completed.