IX. Ajout de l'authentification▲
Attaquons-nous désormais à un aspect important de notre site : l'authentification. Heureusement, Play propose un module pour cela ! Il s'agit du module Secure.
IX-A. Activation du module Secure▲
A l'image du module CRUD, il faut activer le module Secure en modifiant notre fichier /yabe/conf/application.properties, puis redémarrer le serveur :
# Import the secure module
module.secure=${play.path}/modules/secureNormalement, lors du redémarrage, nous devrions être informé que ce module a été chargé.
Comme précédemment, ce module vient avec une série de routes prédéfinies que nous pouvons activer en éditant le fichier /yabe/conf/routes (nous pourrions bien sûr créer nos propres routes, si cela était nécessaire) :
# Import Secure routes
* / module:secureIX-B. Protection de l'interface d'administration▲
En réalité, ce module propose un contrôleur controllers.Secure qui déclare tous les intercepteurs requis. Nous pourrions étendre cette classe Java, mais nous serions alors confrontés à la limitation du simple héritage de Java.
Ainsi, au lieu d'hériter directement de ce contrôleur, nous pouvons annoter notre contrôleur d'administration avec @With, qui indiquera à Play d'invoquer également les intercepteurs adéquats :
package controllers;
import play.*;
import play.mvc.*;
@With(Secure.class)
public class Posts extends CRUD {
}Nous modifions de la même façon les classes Comment, User et Tag.
Si nous souhaitons accéder à la page d'administration, nous arrivons en réalité sur une page de connexion :
Pour l'heure, il suffit de renseigner n'importe quel couple login et mot de passe pour pouvoir passer cet écran.
IX-C. Configuration du processus d'authentification▲
Notre application doit disposer d'une instance du contrôleur controllers.Secure.Security afin de nous permettre de configurer le processus d'authentification. C'est grâce à cette implémentation que nous pourrons spécifier la manière exacte dont les utilisateurs devront s'authentifier.
Créons un fichier /yabe/controllers/Security.java et surchargeons la méthode authentify() :
package controllers;
import models.*;
public class Security extends Secure.Security {
static boolean authentify(String username, String password) {
return true;
}
}Etant donné que nous disposons déjà d'un objet User, il est simple de créer une version fonctionnelle de cette méthode :
static boolean authentify(String username, String password) {
return User.connect(username, password) != null;
}Maintenant, rendons-nous à l'adresse http://localhost:9000/logout pour se déconnecter, et réessayons de se connecter en utilisant cette fois-ci un utilisateur existant dans le fichier data.yml, tel que bob@gmail.com / secret.
IX-D. Refactorisation de l'interface d'administration▲
Nous avions construit notre interface d'administration en nous appuyant sur le module CRUD. Toutefois, cela s'intègre assez mal avec l'aspect visuel du reste du site. Nous allons donc travailler sur une nouvelle interface d'administration. Cette nouvelle mouture permettra à chaque auteur d'avoir accès à ses propres billets. Toutefois, nous conserverons l'administration basée sur le module CRUD pour les "super administrateurs".
Créons un nouveau contrôleur qui gèrera la partie administration :
package controllers;
import play.*;
import play.mvc.*;
import java.util.*;
import models.*;
@With(Secure.class)
public class Admin extends Controller {
@Before
static void setConnectedUser() {
if(Security.isConnected()) {
User user = User.find("byEmail", Security.connected()).first();
renderArgs.put("user", user.fullname);
}
}
public static void index() {
render();
}
}Refactorisons les routes du fichier /yabe/conf/routes :
# Administration
GET /admin/? Admin.index
* /admin module:crudMaintenant, lions le texte "Se connecter pour écrire quelque chose" (Log in to write something) situé dans le fichier /yabe/app/views/main.html à ce contrôleur :
...
<ul id="tools">
<li>
<a href="@{Admin.index()}">Log in to write something</a>
</li>
</ul>
...La dernière étape est de créer le template /yabe/app/views/Admin/index.html, en commençant par quelque chose de simple :
Welcome ${user}!Revenons sur la page d'accueil de notre blog, et cliquons sur ce fameux lien. Si tout s'est bien passé, nous devrions être redirigés vers la nouvelle page d'administration :
C'est un bon début. Comme nous souhaitons disposer de plusieurs pages dans l'interface d'administration, nous allons créer un super template. Choisissons le fichier /yabe/app/views/admin.html pour l'y accueillir :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Administration</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
#{get 'moreStyles' /}
<link rel="stylesheet" type="text/css" media="screen"
href="@{'/public/stylesheets/main.css'}" />
<link rel="shortcut icon" type="image/png"
href="@{'/public/images/favicon.png'}" />
<script src="@{'/public/javascripts/jquery-1.3.2.min.js'}"></script>
<script src="@{'/public/javascripts/jquery.tools.min.js'}"></script>
</head>
<body id="admin">
<div id="header">
<div id="logo">
yabe. <span>administration</span>
</div>
<ul id="tools">
<li>
<a href="@{Secure.logout()}">Log out</a>
</li>
</ul>
</div>
<div id="main">
#{doLayout /}
</div>
<p id="footer">
Yabe is a (not so) powerful blog engine built with the
<a href="http://www.playframework.org">play framework</a>
as a tutorial application.
</p>
</body>
</html>Vous pourrez constater que cela est assez proche de ce que nous avons déjà fait pour la page de garde de notre blog. Nous avons changé le lien de connexion par un lien de déconnexion, qui appelle l'action du contrôleur Secure offert par le module de sécurité.
Faisons désormais usage de ce nouveau template dans le fichier /yabe/app/views/Admin/index.html :
#{extends 'admin.html' /}
Welcome ${user}!Rafraichissons la page :
Si nous nous déconnectons, nous sommes redirigés vers l'écran de connexion :
C'est là la manière classique utilisée par le module de sécurité pour gérer les événements de déconnexion. Cela reste configurable très simplement en surchargeant la méthode onDisconnected() :
static void onDisconnected() {
Application.index();
}Nous pouvons procéder de même avec l'événement onAuthenticated() :
static void onAuthenticated() {
Admin.index();
}IX-E. Ajout des rôles▲
Concrètement, nous avons besoin de deux types d'interface d'administration : la première permettant l'écriture de billet, la seconde pour les super administrateurs. Nous avions ajouté dans la classe User une méthode isAdmin() qui indique justement si cet utilisateur dispose des droits d'administration.
Le module de sécurité offre non seulement le mécanisme d'authentification, mais également la gestion des autorisations. Cela s'appelle les profils. Pour créer un profile administrateur, nous avons juste à surcharger la méthode check() dans la classe controllers.Security :
static boolean check(String profile) {
if("admin".equals(profile)) {
return User.find("byEmail", connected()).<User>first().isAdmin;
}
return false;
}Nous pouvons dès à présent créer un menu dans l'interface d'administration qui dépendra du profil. Modifions le fichier /yabe/view/main.html pour y ajouter un menu en haut :
...
<div id="main">
<ul id="adminMenu">
<li class="${request.controller == 'Admin' ? 'selected' : ''}">
<a href="@{Admin.index()}">My posts</a>
</li>
#{secure.check 'admin'}
<li class="${request.controller == 'Posts' ? 'selected' : ''}">
<a href="@{Posts.list()}">Posts</a>
</li>
<li class="${request.controller == 'Tags' ? 'selected' : ''}">
<a href="@{Tags.list()}">Tags</a>
</li>
<li class="${request.controller == 'Comments' ? 'selected' : ''}">
<a href="@{Comments.list()}">Comments</a>
</li>
<li class="${request.controller == 'Users' ? 'selected' : ''}">
<a href="@{Users.list()}">Users</a>
</li>
#{/secure.check}
</ul>
#{doLayout /}
</div>
...Remarquez comment nous avons utilisé la balise #{secure.check /} pour afficher les options spécifiques aux administrateurs.
Cela n'est toutefois pas suffisant pour protéger la partie CRUD. Si un utilisateur connaît la bonne URL, il pourra y accéder ! Nous devons ainsi protéger les contrôleurs de la même façon. Cela se fait très simplement, grâce à l'annotation @Check. Ainsi, pour le contrôleur Post :
package controllers;
import play.*;
import play.mvc.*;
@Check("admin")
@With(Secure.class)
public class Posts extends CRUD {
}Procédons de même pour les contrôleurs Tags, Comments et Users. Déconnectons-nous, puis essayons de nous connecter avec un utilisateur simple, par exemple jeff@gmail.com / secret. Normalement, nous ne devons pas voir le menu des administrateurs. De plus, une tentative d'accès direct à l'adresse http://localhost:9000/admin/users devrait nous retourner une erreur 403 (accès refusé) :
IX-F. Configurer la mise en page du CRUD▲
Lorsque nous accédons à la partie CRUD de l'interface d'administration, nous perdons la mise en page de cette dernière. Cela est dû au fait que le module CRUD propose sa propre mise en page. Bien sûr, nous pouvons la surcharger. Commençons par lancer cette commande :
> play crud:ov --layoutCela nous crée un fichier /yabe/app/views/CRUD/layout.html. Remplaçons son contenu pour améliorer son intégration au reste de l'application :
#{extends 'admin.html' /}
#{set 'moreStyles'}
<link rel="stylesheet" type="text/css" media="screen"
href="@{'/public/stylesheets/crud.css'}" />
#{/set}
<div id="crud">
#{if flash.success}
<div class="crudFlash flashSuccess">
${flash.success}
</div>
#{/if}
#{if flash.error || error}
<div class="crudFlash flashError">
${error ?: flash.error}
</div>
#{/if}
<div id="crudContent">
#{doLayout /}
</div>
</div>Nous réutilisons le fichier crud.css et l'incluons dans le admin.html en utilisant les mécanismes de get et set des templates. Maintenant, si nous retournons sur les pages du CRUD, nous devrions constater une amélioration de leur intégration :
IX-G. Style de l'écran de connexion▲
Maintenant que notre interface d'administration est cohérente avec le reste de l'application, intéressons-nous à l'écran de connexion. Comme toujours, cet écran est configurable. Lançons la commande suivante :
> play secure:ov --cssNous allons juste conserver le fichier CSS dans son état, mais avant cela, nous importons notre propre CSS (main.css). Ajoutons donc la ligne suivante dans /yabe/public/stylesheets/secure.css :
@import url(main.css);
...Paramétrons finalement les messages de cet écran en ajoutant au fichier /yabe/conf/messages les lignes suivantes :
secure.username=Your email:
secure.password=Your password:
secure.signin=Log in now










