Home > Blockchain >  Vaadin remove pages after login
Vaadin remove pages after login

Time:01-04

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.

  • Related