tete du loic

 Loïc YON [KIUX]

  • Enseignant-chercheur
  • Référent Formation Continue
  • Responsable des contrats pros ingénieur
  • Référent entrepreneuriat
  • Responsable de la filière F2 ingénieur
  • Secouriste Sauveteur du Travail
mail
loic.yon@isima.fr
phone
(+33 / 0) 4 73 40 50 42
location_on
ISIMA
  • twitter
  • linkedin
  • viadeo

[JEE] JSF & Authentification

Date de première publication : 2012/06/07

Objectif et contexte

L'objectif de cet exercice est d'ajouter une sécurité sur notre application web. Comme le sujet est vaste, complexe et toujours glissant, nous n'allons voir que les bases. Comme cela, vous n'aurez pas l'impression malsaine que votre application est blindée.

Mise en place d'une base d'utilisateurs

La première chose à faire est de créer une base d'utilisateurs : identifiant, rôle, mot de passe.

(O) Services > Servers > Glassfish Server (BD) View Domain Admin Console
Configuration > server-config > Sécurité > Domaines (realms) > file (B) Gérer les utilisateurs (B) Nouveau

et saisir les informations suivantes :

Revenir au niveau Sécurité et cocher :
Mise en correspondance par défaut des principaux avec des rôles (Role Mapping Enable)

On associera plus tard les identifiants (Principal) ou les groupes à des rôles utilisateur.

Authentification BASIC

Configuration

On va placer les informations de sécurité dans le fichier de déploiement web.xml. Cela peut se faire directement en XML mais on peut aussi utiliser l'interface graphique de Netbeans.

On suppose que les fichiers à protéger sont dans le répertoire protect de web

Attention : sous Glassfish, les noms de rôle commencent obligatoirement par une majuscule

Il faut maintenant associer rôle et utilisateur ou groupe. Cela se fait en éditant le descripteur de déploiement de Glassfish : glassfish-web.xml (Ce fichier était nommé sun-web.xml dans les versions antérieures à la 3.0)

Si ce fichier n'est pas présent, il faut le créer avec la manipulation suivante :
(N) New file (O) Glassfish > Glassfish descriptor

Il faut maintenant éditer la section Security du fichier

Développer Registered ou le créer comme Security Role Name puis préciser les ou les Principal (Groupes).

Pages protégées

Si le fichier ajout.xhtml se trouve dans le répertoire /protect, vous pouvez constater qu'il est protégé en tapant son url : XXXXX/faces/protect/ajout.xhtml

Mais comment accédez à la page par un lien ?

On utilise souvent la balise commandButton avec l'attribut action. Mais si vous essayez, vous allez constater que la page s'affiche et que la protection

Déconnexion

Le mécanisme d'authentification BASIC n'est pas fait pour la déconnexion. Envoyer une erreur 401 ne marche pas tout le temps. Le meilleur moyen est de fermer le navigateur.

Authentification par formulaire

C'est très similaire à ce que l'on vient de faire. Il suffit de changer le paramétrage du fichier de déploiement. Dans la section Security, cocher FORM et donner le nom d'une page web de connexion et le nom d'une page Web en cas d'erreur de connexion.

Si vos pages sont des pages facelets, il faut penser à la résolution de nom. Par exemple : /faces/login.xhtml.

La page de connexion doit comporter les éléments suivants :

<form method="post" action="j_security_check">
    <h:panelGrid columns="2">
        <h:outputLabel for="j_username">Identifiant :</h:outputLabel>
        <h:inputText id="j_username"/>
        <h:outputLabel for="j_password">Mot de passe :</h:outputLabel>
        <h:inputSecret id="j_password" />
    </h:panelGrid>
    <h:commandButton value="Se connecter" />
</form>

Notez bien que l'on ne peut pas utiliser de formulaire JSF, cela ne marcherait pas.

Le tutorial propose page 748 une autre méthode assez sympathique également. Il faut écrire un formulaire (JSF) paramétré par les attributs login et mdp. L'action à réaliser est la suivante :

public void login() {
    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
    try {
        request.login(login, mdp);
        context.addMessage(null, new FacesMessage("Et hop, reconnu"));
    } catch (ServletException e) {
        // Handle unknown username/password in request.login().
        context.addMessage(null, new FacesMessage("Unknown login "+e.getMessage()));
        // éventuellement log.log(Level.SEVERE, "Failed to logout user!", e);
        // avec private static Logger log = Logger.getLogger(AuthBackingBean.class.getName());
    }
}

Cette méthode est pratique :

Maintenant pour gérer une déconnexion, c'est beaucoup plus facile, il suffit d'invalider la session ou d'utiliser logout().

Voilà c'est tout pour cette découverte de la sécurisation. Prochaine étape : JAAS et sécurisation par base de données.