lunes, 15 de abril de 2019

14. VaadinServiceInitListener: Preventing non authorised access.

updated on April 15, 2019

0. Introduction

Vaadin provides a BeforeEnterEvent in forms that can be used to detect unauthorised login attempts and enables us to redirect to a login form.

1. Declaring a VaadinServiceInitListener

We should:
  1. Create a folder called "META-INF" in the src/main/resources folder.
  2. Create a folder called "services" in the previously created META-INF folder.
  3. Add a text file called "com.vaadin.flow.server.VaadinServiceInitListener", with this content (that is the absolute class name if the 


openadmin.listeners.LoggedInListener

Here is a schema:

-->src
   |-->main
      |-->resources
         |-->META-INF
            |-->services
               |-->com.vaadin.flow.server.VaadinServiceInitListener

2. The VaadinServiceInitListener interface

A class that extends this interface is created and:
  1. Add a BeforeEventListener to the UI that is requested by the user
  2. If the session attribute "CURRENT_USER" is null then the user is redirected to the "LoginForm".
  3. So the user cannot access any other form in the application unless the CURRENT_USER is set to not NULL value.
  4. I have named this class LoggedInInstener (for detecting if a user is logged in), and must coincide with the content of the file "com.vaadin.flow.server.VaadinServiceInitListener" while declaring the VaadinServiceInitListener in the previous point.
  5. Note that we cannot inject session scoped beans in this listener!!!! But... we can access the session!.
Here is the code:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package openadmin.listeners;

import com.vaadin.flow.server.ServiceInitEvent;
import com.vaadin.flow.server.VaadinServiceInitListener;

import openadmin.ui.LoginForm;
import openadmin.utils.VaadinUtils;


/**
 * This class is used to listen to BeforeEnter event of all UIs in order to
 * check whether a user is signed in or not before allowing entering any page.
 * It is registered in a file named
 * com.vaadin.flow.server.VaadinServiceInitListener in META-INF/services.
 * 
 * NOTE that a SessionScopped object cannot be injected so, to know if the user is logged in
 *   we need to make use of information stored in the Session object with keys "CURRENT_USER" 
 */
@SuppressWarnings("serial")
public class LoggedInListener implements VaadinServiceInitListener {
 
 public LoggedInListener() {
  System.out.println("A new LoggedInListener has been created....");
  
 }
 
 
 @Override
    public void serviceInit(ServiceInitEvent initEvent) {
     initEvent
      .getSource()  // gets the object that raised the event
      .addUIInitListener( // Adds a listener that gets notified when a new UI has been initialized.
       uiInitEvent -> { // A UIInitListener
        uiInitEvent
         .getUI() // Get the initialized UI for this initialization event
         .addBeforeEnterListener( //Add a listener that will be informed when a new set of components are going to be attached
          enterEvent -> { // a BeforeEnterEvent
           // If the Session attribute "CURRENT_USER" is not set, then redirect to LoginForm class
           if (VaadinUtils.getSessionAttribute("CURRENT_USER")==null) { 
            if (!LoginForm.class.equals(enterEvent.getNavigationTarget())) {
             enterEvent.rerouteTo(LoginForm.class); 
             System.out.println("LoggedInListener: Session attribute 'CURRENT_USER' is null ....");
            } 
           }
         });
      });
    }
}



No hay comentarios:

Publicar un comentario