Handling login with a Vaadin Flow webapp, across a

2019-05-21 14:55发布

问题:

Vaadin 8

In Vaadin 8, in my UI subclass I handled login by examining if a user’s session carried an attribute noting whether they had successfully logged in or not. If not, my UI subclass displayed a login layout rather than other content with navigation options such as menu bar and buttons that switch layout within that UI.

Vaadin 10+

In Vaadin 10 and later, Vaadin Flow, the UI class is apparently handled automatically by Vaadin in a manner transparent to me the app developer. Now the @Route and Router class approach is suggested as the way to navigate between forms, driven by different URLs attached to each layout. One benefit is the user being able to bookmark a location within the app, in friendly web style.

Global check

➥ In Vaadin Flow, how does one handle a global check that the user is logged-in before displaying any other content?

Subclass UI, as in Vaadin 8

Should I follow the Vaadin 8 approach, writing a subclass of UI? If so, how to install my subclass of UI in place of the UI apparently apparently placed automatically by Vaadin Flow?

Do I follow the example shown in the manual with a Servlet definition, and as discussed in this other Question?

BeforeEnterEvent

Or should I be doing something with the BeforeEnterEvent discussed in routing lifecycle tutorial? While the top of that page has a brief mention of listeners firing on the UI instance, the examples across the rest of the page involve code on the layout rather than UI. So I do not understand how to handle global check across all my current and future layouts defined in my app.


My question has nothing to do with storing passwords, credentials, hash & salt, etc. I am asking about a way to gracefully check for login being completed to block/grant access to the content of a Vaadin web app.

回答1:

There are a couple of different alternatives that might be useful for you, slightly depending on how you've structured you application.

  1. Make your main layout class implement BeforeEnterObserver. This is a really simple approach as long as you only have one main layout for the entire application. One drawback is that there would be no checks for any @Route class that you don't configure to directly or indirectly use your main layout.
  2. Implement RouterLayout.showRouterLayoutContent in your main layout (instead of relying on the default implementation), and do the checks there. This again only works when the main layout is actually used for all views, but might be challenging if having intermediate layouts in between.
  3. Define your own AbstractView class that does access control on its own for each instance. This again requires that you remember to always use AbstractView for all your routes.
  4. Register a UI-wide BeforeEnterListener that performs access checks. This is a little more complex to set up since you'd need a VaadinServiceInitListener that adds a UIInitListener that adds the actual listener. On the other hand, this approach is able to intercept any navigation event regardless of layout nesting and without requiring a special view class.