Как обрабатывать доступ к представлениям, если пользователь еще не аутентифицирован? - PullRequest
2 голосов
/ 14 января 2020

Главная страница моего Vaadin 14 - это MainView с маршрутом root.

MainView используется в качестве «шаблона» для другого представления (с layout = MainView.class), поэтому я вижу его больше как «абстрактное» представление, которое не должно инициализироваться само по себе и используется только для другие представления как макет.

Теперь проблема: если пользователь обращается к MainView, BeforeEnterEvent называется ПОСЛЕ конструктора . Это может привести к возникновению исключений, потому что пользователь еще не аутентифицирован, а конструктор выполняет такие вещи, как создание вкладок.

Есть ли способ запретить пользователю доступ к маршруту MainView или событие, которое выполняется перед вызовом конструктора? Доступ к представлению разрешен только при аутентификации пользователя.

@Route("")
public class MainView extends AppLayout implements BeforeEnterObserver {

public MainView() {
    super();

    // Creates all the Tabs that are used in the MainView, may throw exception if the user calls the URL of this View before authenticated
    setupView();
}

...

@Override
public void beforeEnter(BeforeEnterEvent event) {
    // Reroute to Login if User is NOT authenticated
}
}

@Route(value = "foo", layout = MainView.class)
public class OtherView {

Обновление:

Исправление выпущен в качестве экспериментальной функции в Vaadin 14.2 .

Ответы [ 3 ]

3 голосов
/ 14 января 2020

Проблема с созданием экземпляров слишком рано была фактически закрыта через несколько часов go. Пройдет некоторое время, прежде чем он будет выпущен.

При этом метод экземпляра невозможно вызвать до конструктора, поэтому он не исправляет ваш конкретный случай.

Я бы предложил переместив код настройки вида на onAttach. Если вы хотите запустить установочный код только один раз, вы можете использовать AttachEvent#isInitialAttach только для выполнения кода при первом присоединении.

Как только проблема, которую я связал выше, будет разрешена, вы можете иметь код в конструкторе. , но экземпляр, имеющий метод наблюдателя, будет по-прежнему создаваться до вызова beforeEnter, но не экземпляры дочерних представлений.

Чтобы не создавать никаких представлений, вы можете добавить прослушиватель непосредственно в пользовательский интерфейс, используя UI#addBeforeEnterListener как только пользовательский интерфейс будет создан, используя слушатель инициализации пользовательского интерфейса . Опять же, только когда исправление было выпущено.

2 голосов
/ 14 января 2020

Ваш код может иметь проблему безопасности , как описано в серии учебников для обеспечения безопасности пружин с помощью Vaadin . объясняется, как вместо этого защищать представления в VaadinServiceInitListener.

Но предлагаемое решение также добавляет beforeEnterListener к представлениям, поэтому я не думаю, что ваша проблема решается с помощью этого.
Решением вашей проблемы может быть создание специального исключения (давайте назовем его NotAuthorizedException для дальнейшей ссылки) в конструкторе MainView, если пользователь не авторизован. Затем вы позволяете вашему LoginView реализовать HasErrorParameter<NotAuthorizedException>

0 голосов
/ 15 января 2020

Мне удалось временно исправить это с помощью дополнительной проверки подлинности. Возможно, это не лучшее решение, но пока оно работает. В будущем ответ @ Tazavoo должен быть реализован.

public MainView() {
    super();
    if (!isAuthenticated()) 
       return;

    setupView();
}
...