Ellipse Tutorial

Comment utiliser le composant ?

AccueilNotre catalogue de formationsNos partenairesDemande de devisEllipse FrameworkJWT (Javascript Widget Toolkit)License d'exploitation de nos logicielsVos développements sur mesuresTutorial sur le langage CSSTutorial sur le langage XMLTutorial sur le langage JavaTutorial sur le langage Visual Basic 6.0Historique de la sociétéNous contacterA propos de ce site
 

ATTENTION : Tutorial en cours d'écriture ! N'hésitez pas à nous signaler toute erreur ou suggestion.

Accès rapide :
   Présentation du moteur de sécurité du framework Ellipse
   Utilisation du composant <web:LoginForm>

Qui dit application Web, dit besoin de sécuriser les accés à cette application. D'ailleurs, cela est aussi souvent vraiment pour les applications non Web. Ce qui serait dommage, c'est de devoir réécrire un moteur de sécurité pour cette nouvelle application (avec un support de persistance, pourquoi pas vers une base de données relationnelles). C'est pour cela que le framework Ellipse propose un moteur de sécurité minimal. Il ne couvre pas une infinité de besoins, mais il est probable qu'il suffise à la majorité des cas. Il est important de remarquer qu'il a été architecturé de manière à permettre son extension, si d'aventure vous souhaitez l'enrichir. Notez aussi qu'en fait il y a deux parties bien distinctes dans ce qui va vous être présenté dans ce document. D'un côté, il y a le moteur de sécurité : il peut, sans difficulté, fonctionner pour des applications Web ou non Web. D'autre part, il y a le composant <web:LoginForm> : il s'utilise dans un formulaire Web Ellipse et se base sur le moteur de sécurité précédemment cité (dans ce cas, on considère forcément une application Web Ellipse).

Présentation du moteur de sécurité du framework Ellipse

Un moteur de sécurité doit, normalement, permettre deux types de mécanismes : l'authentification et l'autorisation. L'authentification consiste à identifier un utilisateur à partir d'un certain nombre d'informations : dans le cas du moteur de sécurité Ellipse, on en considère uniquement deux (le login et le password). Si une personne n'est pas authentifiée, l'accès à l'application lui est refusé. L'autorisation consiste, une fois un utilisateur authentifié, à lui donner accés (ou non) à un certain nombre de resources. Par exemple, si l'utilisateur Toto (avec son mot de passe Titi) à un role d'administrateur, alors il pourra avoir accès aux pages d'administration de l'application. Dans le cas contraire, l'utilisateur (connecté à l'application) ne pourra pas accéder à ces pages. Mais il est envisageable qu'il puisse accéder à d'autres pages moins sensible en termes de sécurité.

Attention : dans l'état actuel des choses, le framework Ellipse ne gère que l'authentification. Mais dans un avenir plus ou moins proche, des possibilités en termes d'autorisations seront adjointes au framework.

Il faut aussi noter que les informations de sécurité doivent être persistante. Cela veux dire qu'on doit pouvoir sauvegarder ces informations sur un support persistant : pourquoi pas un annuaire X500 (active directory par exemple), une base de données (MySql ou autre), dans un fichier (XML ou autre) ou sur tout autre types de supports persistant. Il est important qu'une solution de sécurité puisse permettre d'envisager un grand nombre de cas. Le framework Ellipse anticipe ces possibilités en architecturant son moteur de sécurité autour d'un certain nombre d'interfaces Java. Ainsi, si une possibilité n'est actuellement pas supportée, il sera plus ou moins simple d'envisager d'étendre le système en fournissant de nouvelles implémentations pour les interfaces considérées.

Attention : toujours dans l'état actuel des choses, seules une persistance au sein d'une base de données relationnelle a été implémentée. Qui plus est, seules les bases de données MySql et JavaDB (aussi connue sous le nom de Derby) ont étaient testées (ce choix n'est pas annodin : il s'agit des deux bases de données fournies par Sun Microsystems). Plus tard, d'autres possibilités seront supportées. Mais gardez à l'esprit qu'il vous est possible de coder vos propres implémentations.

Il y a trois interfaces a connaitre pour utiliser le moteur de sécurité intégré au framework Ellipse. Elles se nomment : corelib.security.SecurityManager, corelib.security.UserManager et corelib.security.RoleManager. Analysons l'une après l'autre ces interfaces. La première, corelib.security.SecurityManager, constitue le point d'entrée sur le service de sécurité. En voici son contenu.

 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 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
package corelib.security;

/**
 * <p>
 *     This interface defines methods for access to a security service. A security
 *     service must provide two mechanisms: authentication and permissions management.
 *     Authentication consist to identify a user and enable him (or not) connecting
 *     to the considered system. The management of permissions allows, once the user
 *     authenticated, him to have an access (or not) to resources.
 * </p>
 * 
 * <p>
 *     In the current version of the Ellipse framework, only authentication is supported.
 *     But a future version of the framework will add the concepts of permissions. The
 *     Ellipse framework provides the JdbcSecurityManager class : this is, of course,
 *     an implementation of this interface that use a relational database to store
 *     the security informations.
 * </p>
 * 
 * @see corelib.security.JdbcSecurityManager
 * @see corelib.security.RoleManager
 * @see corelib.security.UserManager
 * 
 * @author Dominique Liard
 * @since 0.3.6
 */
public interface SecurityManager {

    /**
     * Open a session to the considered security service.
     * 
     * @throws SecurityManagerException    Thrown when connection to the security
     *            service cannot be established.
     */
    public void openSession() throws SecurityManagerException;
    
    /**
     * Close the session with the considered security service.
     * 
     * @throws SecurityManagerException    Thrown when connection to the security
     *         service cannot be closed.
     */
    public void closeSession() throws SecurityManagerException;
    
    /**
     * Returns the role manager associated to this security manager. 
     * A role manager provided methods to manage roles.
     * 
     * @return The role manager associated to this security manager. 
     */
    public RoleManager getRoleManager();
    
    /**
     * Returns the user manager associated to this security manager.
     * A user manager provided methods to manage users.
     * 
     * @return The user manager associated to this security manager. 
     */
    public UserManager getUserManager();    
    
}
Content of the SecurityManager interface.

Quatre méthodes sont exposées par cette classe. Les deux premières permettent respectivement d'ouvrir et de fermer une session à système utilisé pour stocker les informations de sécurité (certainnement une base de données relationnelles, mais on peut envisager qu'il sagisse d'un autre système). Les deux autres méthodes permettent d'obtenir deux instances : un instance de type UserManager et une instance de type RoleManager. Ces deux objets permettront de gérer les utilisateurs et les roles. Voici le contenu de l'interface UserManager.

 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 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
 79 
 80 
 81 
 82 
 83 
 84 
package corelib.security;

import corelib.security.AccountDisabledException;
import corelib.security.BadCredentialsException;
import corelib.security.SecurityManagerException;
import corelib.security.User;
import corelib.security.UserAlreadyRegisteredException;

/**
 * This interface defines the methods used to manage User instances.
 * To can get a UserManager instance by asking it at your SecurityManager.
 * 
 * @see corelib.security.SecurityManager
 * @see corelib.security.JdbcSecurityManager
 * @see corelib.security.User
 * 
 * @author Dominique Liard
 * @since 0.3.6
 */
public interface UserManager {

    /**
     * Check if the pair login/password represents an autorized user for the considered
     * application. If the identity is rejected, an exception will thrown. If the
     * identity is accepted, the connection number of the considered user is increased.
     * 
     * @param userLogin     The login for the considered user.
     * @param userPassword  The password for the considered user.
     * @return              The considered user instance.
     * 
     * @throws AccountDisabledException  Thrown when the provided account informations there invalid.
     * @throws BadCredentialsException   Thrown if the identity is rejected.
     */
    public User checkCredentials( String userLogin, String userPassword ) throws AccountDisabledException, BadCredentialsException;
    
    /**
     * Insert a new user in the security system. The new used has the specified
     * login and the specified password.
     * 
     * @param login         The login for the considered user.
     * @param password      The password for the considered user. The specified password
     *                      is automaticly encoded by this method.
     * @return              The new user instance.
     * 
     * @exception SecurityManagerException
     *            Thrown if the new user cannot be inserted in the security system. 
     * @exception UserAlreadyRegisteredException
     *            Thrown if the specified login is already registered in the security system.
     */
    public User insertUser( String login, String password ) throws UserAlreadyRegisteredException, SecurityManagerException ;
    
    /**
     * Update informations, in the security system, for the specified user.
     * 
     * @param user  The user instance to update.
     * 
     * @throws SecurityManagerException
     *         Thrown if this manager cannot update the user informations.
     */
    public void updateUser( User user ) throws SecurityManagerException ;
    
    /**
     * Delete the specified user from the security system.
     * 
     * @param user    The user to delete.
     * 
     * @throws SecurityManagerException
     *         Thrown if this manager cannot remove the user.
     */
    public void deleteUser( User user ) throws SecurityManagerException ;
    
    /** 
     * Defines the algorithm used for encode password. User password is stored in 
     * encoded format.
     * 
     * @param clearPassword       A password (in clear).
     * @return                    The encoded password.
     * 
     * @throws SecurityManagerException
     *         Thrown if password encription failed.
     */
    public String encryptPassword( String clearPassword ) throws SecurityManagerException;
    
}
Content of the UserManager interface.

La première méthode de cette interface est certainnement la principale : c'est elle qui permet de savoir si les informations fournies par un utilisateur constituent effectivement une identité autorisée. Si c'est le cas un objet de type User vous sera retourné (pour de plus amples informations sur le contenu de la classe User, je vous renvoie vers la documentation Javadoc). Dans le cas contraire, une exception sera déclenchée. Les autres méthodes permettent respectivement d'insérer un nouvel utilisateur, de mettre à jours les informations d'un utilisateur et de supprimer un utilisateur. Notez aussi que la dernière méthode permet de retrouver la forme encryptée d'un password (une fois un password inséré dans le système de sécurité, il ne vous sera plus possible d'en retrouver la version d'origine (en clair). Le fait que les mots de passe soient systématiquement encryptés permet, bien entendu, de garantir un maximum de sécurité.

 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 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
package corelib.security;

/**
 * This interface defines the methods used to manage Role instances.
 * To can get a RoleManager instance by asking it at your SecurityManager.
 * 
 * @see corelib.security.SecurityManager
 * @see corelib.security.JdbcSecurityManager
 * @see corelib.security.Role
 * 
 * @author Dominique Liard
 * @since 0.3.6
 */
public interface RoleManager {

    /**
     * Select the role with the identifier specified in parameter.
     * 
     * @param roleIdentifier    The identifier of the role to returns. 
     * @return                    The selected role.
     * 
     * @exception SecurityManagerException
     *         Thrown if the searched role don't exists.
     */
    public Role selectRoleById( int roleIdentifier ) throws SecurityManagerException ;
    
    /**
     * Select the role with the name specified in parameter.
     * 
     * @param roleName        The name of the role to returns.
     * @return                 The selected role.
     * 
     * @exception SecurityManagerException
     *         Thrown if the searched role don't exists.
     */
    public Role selectRoleByName( String roleName ) throws SecurityManagerException ;
    
    /**
     * Insert a new role into the used security system.
     * 
     * @param roleName        The name of the new role.
     * @return                The new role.
     * 
     * @exception SecurityManagerException
     *         Thrown if the role cannot be inserted into the security system. 
     * @exception RoleAlreadyRegisteredException
     *         Thrown if the specified role name already exists in the security system.
     */
    public Role insertRole( String roleName ) throws SecurityManagerException ;
    
    /**
     * Update the informations for this role (actually, only the role name).
     * 
     * @param role    The role to update.
     * 
     * @exception SecurityManagerException
     *         Thrown if the role cannot be updated into the security system.
     */
    public void updateRole( Role role ) throws SecurityManagerException ;
    
    /**
     * Delete, on the security system, the specified role.
     * 
     * @param role    The role to delete.
     * @exception SecurityManagerException
     *         Thrown if the specified role cannot be deleted from the seciry system.
     */
    public void deleteRole( Role role ) throws SecurityManagerException ;

}
Content of the RoleManager interface.

Cette interface est en fait très similaire à la précédente, bien qu'un peu plus simple. Notons néanmoins qu'elle porte sur la manipulation des rôles qui vont être affectés aux utilisateurs.

Nous allons maintenant utiliser ces interfaces pour mettre en oeuvre un système de sécurité basé sur une base de données relationnelle. Pour ce faire, nous allons utiliser des implémentations de ces interfaces, basées sur JDBC(Java DataBase Connectivity) pour prendre en charge la connexion avec la base de données. Je vous rappelle que pour l'heure seules MySql et JavaDB (Apache Derby, c'est la même chose) sont supportées. Notez un point important : lors de la première utilisation de ces classes, si la base de données utilisée ne contient pas les tables attendues pour stocker les informations, le framework Ellipse les créera automatiquement : vous n'avez aucune action particulière à réaliser pour construire les tables dans la base. Vous vous appercevrez certainnement, à l'utilisation, que cela est fort pratique et que cela permet de gagner pas mal de temps. Il ne vous restera plus qu'a y injecter vos éventuels premiers utilisateurs et roles. L'exemple ci-dessous vous montre un exemple d'utilisation d'un moteur de sécurité (basé sur JDBC) fonctionnant dans une application Java en mode console (démarrant par un bon vieux main).

 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 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
 79 
 80 
 81 
 82 
 83 
 84 
 85 
 86 
 87 
 88 
 89 
 90 
 91 
 92 
 93 
 94 
 95 
 96 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import corelib.security.JdbcSecurityManager;
import corelib.security.Role;
import corelib.security.RoleManager;
import corelib.security.SecurityManagerException;
import corelib.security.User;
import corelib.security.UserManager;
import corelib.utilities.jdbc.DataSource;


public class SecurityManagerSample {

    private static BufferedReader keyboard = new BufferedReader(
        new InputStreamReader( System.in )
    );
    
    private DataSource dataSource = null;
    private JdbcSecurityManager securityManager = null;
    private UserManager userManager = null;
    private RoleManager roleManager = null;

    
    public SecurityManagerSample() throws SecurityManagerException {
        this.dataSource = new DataSource() {
            @Override public String getDriver() { return "com.mysql.jdbc.Driver"; }
            @Override public String getUrl() { return "jdbc:mysql://localhost/DemoDB"; }
            @Override public String getLogin() { return "theDbLogin"; }
            @Override public String getPassword() { return "theDbPassword"; }
        };
        this.securityManager = new JdbcSecurityManager( this.dataSource );
        this.userManager = this.securityManager.getUserManager();
        this.roleManager = this.securityManager.getRoleManager();
    }
    
    public void init() throws SecurityManagerException {
        Role adminRole = this.roleManager.insertRole( "Administrator" );
        Role userRole = this.roleManager.insertRole( "Simple User" );
        
        User root = this.userManager.insertUser( "root", "azerty" );
        root.addRole( adminRole );
        root.addRole( userRole );
        this.userManager.updateUser( root );
        
        User toto = this.userManager.insertUser( "toto", "qwerty" );
        toto.addRole( userRole );
        this.userManager.updateUser( toto );
    }    
    
    public void run() throws SecurityManagerException, IOException {
        System.out.println( "Secure system: logon is required." );
        
        while( true ) {
            System.out.print( "Login: " );
            String strLogin = keyboard.readLine();
            
            System.out.print( "Password: " );
            String strPassword = keyboard.readLine();
            
            try {
                User user = this.userManager.checkCredentials( strLogin, strPassword );
                System.out.println( "Welcome " + user.getLogin() );
                break;
            } catch( Exception exception ) {
                System.out.println( "Login failed, please retry" );
            }
        }

        System.out.println( "Bye" );
    }
    
    public void destroy() throws SecurityManagerException {
        this.userManager.deleteUser(
            this.userManager.checkCredentials( "root", "azerty" ) );
        this.userManager.deleteUser(
            this.userManager.checkCredentials( "toto", "qwerty" ) );
        
        this.roleManager.deleteRole( 
            this.roleManager.selectRoleByName( "Administrator" ) );
        this.roleManager.deleteRole( 
                this.roleManager.selectRoleByName( "Simple User" ) );
    }
    
    public static void main( String[] args ) throws Exception {
        SecurityManagerSample sample = new SecurityManagerSample();
        try {
            sample.init();
            sample.run();
        } finally {
            sample.destroy();
        }
    }
    
}
Utilisation du moteur de sécurité.

Ce code est relativement simple. Un main démarre le programme en créant une instance sur la classe SecurityManagerSample : ce constructeur initialise le moteur de sécurité à partir du DataSource identifiant votre base de données. Ensuite, ce main invoque trois méthodes. La première, init, créer deux utilisateurs dans la base, ainsi que les rôles associés. La seconde, run, vous demande de saisir un login et un password afin de tenter une connexion au système. Enfin, la dernière méthode, destroy, détruit les éléments créer par la méthode init.

Attention : il est a noter un point important. Le moteur de sécurité d'Ellipse permet la désactivation d'un compte utilisateur. Si trois tentatives de connexion successives échouent, ce pour un même login, alors le compte sera marqué comme étant désactivé. A partir de ce moment, il ne sera plus possible d'utiliser ce compte, même en fournissant un password valide. Pour réactiver le compte, il faudra repasser, au niveau de la base de données, le champs IsDisabled de l'utilisateur considéré à la valeur 0 (false);

Pour compiler ce programme, il vous faudra utiliser le jar du framework Ellipse (javac -cp EllipseFramework.jar SecurityManagerSample.java). Pour exécuter cet exemple, il vous faudra aussi utiliser le framework Ellipse, mais il vous faudra aussi avoir le jar pour le driver JDBC permettant la connexion à la base de données MySql. Vous pouvez télécharger ce jar (dans sa dernière version) directement sur le site http://www.mysql.com. La ligne de commande permettant l'exécution du programme devrait ressembler à : java -cp EllipseFramework.jar:mysql-connector-java-5.1.7-bin.jar:. SecurityManagerSample.

Utilisation du composant <web:LoginForm>

Le framework Ellipse propose un composant Web prêt à l'emploi pour envoyer les informations saisies au moteur de sécurité. Son utilisation est relativement simple : il faut simplement lui fournir le nom du DataSource à utiliser pour la connexion à la base de données. Notez aussi qu'il est possible de modifier le style visuel de votre formulaire d'authentification par le biais d'une feuille de style CSS.

Commençons par définir notre DataSource. Dans le cadre d'une application Web Ellipse, il est possible de définir un descripteur de déploiement (un fichier XML) spécifique aux sources de données utilisées. Ce descripteur de déploiement sera chargé par le framework au démarrage de votre application Web. Ce fichier XML doit obligatoirement se nommer datasources.xml et il doit obligatoirement être localisé dans le répertoire WEB-INF de votre WAR(Web ARchive) .

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
<?xml version="1.0" encoding="ISO-8859-1"?>
<DataSources>

    <DataSource name="DemoDataSource" description="Demo data source">
        <DriverClassName>com.mysql.jdbc.Driver</DriverClassName>
        <ConnectionURL>jdbc:mysql://localhost:3306/DemoDB</ConnectionURL>
        <Login>theDbLogin</Login>
        <Password>thedbPassword</Password>
    </DataSource>

</DataSources>
Descripteur de déploiement datasources.xml

Si nécessaire, vous pouvez, dans une classe de page Ellipse, retrouver votre instance de DataSource via l'instruction suivante : DataSource dataSource = this.getApplication().getDataSourceSet().getDataSource( this.getDataSourceName() );. C'est exactement ce que va utiliser votre composant FormLogin pour retrouver les informations nécessaires à la connexion à la base de données.

Il nous faut maintenant définir une page Web qui incorpore un composant de formulaire d'authentification. Comme vous pouvez l'observer dans l'exemple ci-dessous, la ligne 13 définie notre instance de composant de formulaire d'authentification. Pour que cela fonctionne, il faut bien entendu que l'espace de nom XML security ait été défini. Cette définition se trouve au niveau de la ligne 3 : elle associe à cet espace de nom le package Ellipse corelib.services.web.components.security. Notez aussi que lors de la définition de notre composant d'authentification, on l'associe à la source de donnée DemoDataSource par le biais de l'attribut dataSourceName (ligne 13).

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
<?xml version="1.0" encoding="ISO-8859-1" ?>
<web:Html xmlns:web="corelib.services.web.components"
          xmlns:security="corelib.services.web.components.security"
          codeBehind="corelib.services.web.webapplications.WebPage">
    <head>
        <title>LoginForm Samples</title>
        <link rel="stylesheet" type="text/css"
              href="corelib/services/web/javascript/jwt/Jwt.css" />
    </head>
    <body>
        <h1 align="center">LoginForm Samples</h1> <br/>
        
        <security:LoginForm dataSourceName="DemoDataSource" />
        
    </body>
</web:Html>
La page web d'authentification

Le composant d'authentification LoginForm supporte un certain nombre d'événements. Ils déclenchent en fonction du résultat d'une tentative de connexion. Trois événements sont sonpportés par l'interface d'écoute corelib.services.web.components.events.LoginFormListener. A titre indicatif, voici le contenu de cette interface (notez les trois méthodes correspondantes aux trois événements supportés).

 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 
package corelib.services.web.components.events;

import corelib.services.web.webapplications.events.WebListener;

/**
 * This interface defines event handlers used during connection by the FormLogin web component.
 * 
 * @author Alexia Ramaioli & Dominique Liard
 * @since 0.4.0
 */
public interface LoginFormListener extends WebListener {

    /**
     * Fired when a connection is made with a correct identity.
     * @param event    The object that qualified this event. 
     */
    public void loginSuccessed( LoginFormEvent event );

    /**
     * Fired when a connection is made with a wrong identity.
     * @param event    The object that qualified this event. 
     */
    public void loginFailed( LoginFormEvent event );
    
    /**
     * Fired when a connection is made with a identity that was deactivated.
     * @param event    The object that qualified this event. 
     */
    public void accountDisabled( LoginFormEvent event );
    
}
Interface d'écoute corelib.services.web.components.events.LoginFormListener.