- Blog Xebia France - http://blog.xebia.fr -
Grails Spring Security Plugin, la sécurité facile
Posted By Aurélien Maury On Jeudi 25 février 2010 @ 10:00 In Java / JEE | 11 Comments
Le monde Grails a le vent en poupe ces temps-ci. Bien avant le printemps on peut voir fleurir des dizaines de tutoriaux sur le net pour prendre l’outil en main et créer sa première application. Mais un simple « Getting started » ne suffit pas toujours à bien prendre la mesure de la puissance de Grails.
Je vous propose donc un petit tutoriel pour mettre en place une gestion des utilisateurs, avec gestion des rôles, filtres URL/Rôles, formulaire de souscription de compte. Pour cela, nous allons nous appuyer sur le Spring Security Plugin de Grails. C’est une étape incontournable de la création d’application, et nous allons pouvoir constater à quel point l’utilisation de Grails booste la productivité.
Commençons par créer l’application BookStore qui nous servira de base, ainsi qu’une classe de domaine Book.
grails create-app BookStore cd BookStore grail create-domain-class fr.xebia.bookstore.common.Book
Apportons quelques modifications à notre classe pour qu’elle soit un peu plus parlante dans la suite des exemples :
grails-app/domain/fr/xebia/bookstore/common/Book.groovy
package fr.xebia.bookstore.common
class Book {
String titre
String auteur
Date premierePublication
static constraints = {
titre(nullable:false)
auteur(nullable:false)
}
}
Maintenant nous générons le CRUD autour de notre classe Book.
grails generate-all fr.xebia.bookstore.common.Book
Installation du plugin Spring Security. Pas de panique, acegi est toujours le nom du plugin, c’est un héritage de l’histoire
grails install-plugin acegi
Creation des classes de domaines pour la gestion de la sécurité, Utilisateur, roles et mapping de security et génération des managers associés
grails create-auth-domains
fr.xebia.bookstore.security.User
fr.xebia.bookstore.security.Role
fr.xebia.bookstore.security.RequestMap
grails generate-manager
Maintenant nous générons les composants nécessaires à la souscription d’un compte par un internaute.
grails generate-registration
A ce stade, nous disposons des contrôleurs suivants (et des vues qui vont avec) :
BookOn peut déjà démarrer l’application avec un grails run-app et voir ce que ça donne :

Cela fait déjà beaucoup de matières à exploiter en un temps relativement court. Mais en l’état c’est encore un peu brut de fonderie pour ressembler à une vraie application. Nous allons donc faire un peu de configuration et de rangement autour de tout ce code parachuté par Grails. Pour atteindre notre objectif, nous allons maintenant procéder à la sécurisation des écrans de :
BookTout est déjà en place pour cela grâce au code que nous avons généré. Commençons par utiliser le RoleController pour créer un rôle utilisateur et un rôle administrateur :

Maintenant que nous avons des rôles, il faut créer un compte utilisateur avec le rôle ROLE_ADMIN pour éviter de se retrouver bloqué quand on posera les mappings de sécurité. Cette fois, c’est du coté des écrans du UserController que ça se passe :

Et pour finir, on pose des mappings de sécurité sur les URL qui nous intéressent, avec la liste des rôles autorisés à accéder. Pour cela, nous utilisons le RequestMapController :

Et voilà ! Notre application répond déjà mieux à nos attentes en terme de sécurité :
Book présents en base.BookSi un utilisateur non authentifié tente d’accéder à une URL protégée, il sera automatiquement redirigé vers un écran de login avant d’accéder à la page désirée.
Par défaut, une application Grails utilise HSQLDB et démarre avec une base vierge à chaque lancement. Nous allons donc changer cela pour intégrer directement à chaque démarrage les rôles, mappings de sécurité et un compte administrateur :
grails-app/conf/BootStrap.groovy
import fr.xebia.bookstore.security.User
import fr.xebia.bookstore.security.Role
import fr.xebia.bookstore.security.RequestMap
class BootStrap {
def authenticateService
def init = { servletContext ->
def roleAdmin = new Role(authority: 'ROLE_ADMIN', description: 'Administrateur').save()
def roleUser = new Role(authority: 'ROLE_USER', description: 'Utilisateur').save()
def userAdmin = new User(username: 'admin', userRealName: 'ATTAN Charles',
passwd: authenticateService.encodePassword('admin'),
enabled: true, email: 'admin@bookstore.fr')
userAdmin.addToAuthorities(roleAdmin)
userAdmin.save()
def protectBookCreation = new RequestMap(url: '/book/create*', configAttribute: 'ROLE_ADMIN,ROLE_USER').save()
def protectUserManaging = new RequestMap(url: '/user/*', configAttribute: 'ROLE_ADMIN').save()
def protectRoleManaging = new RequestMap(url: '/role/*', configAttribute: 'ROLE_ADMIN').save()
def protectSecurityMappingManaging = new RequestMap(url: '/requestMap/*', configAttribute: 'ROLE_ADMIN').save()
}
def destroy = {
}
}
Voilà, au prochain démarrage nous retrouverons toutes nos chères données directement en base. Ensuite, nous pouvons nous attaquer à l’enregistrement des internautes en tant qu’utilisateur standard. Par défaut, le formulaire lié au RegisterController crée des utilisateurs sans rôle, ce qui ne nous convient pas du tout. De plus, comme il serait agréable pour les nouveaux utilisateurs de recevoir un mail de confirmation de leur inscription, on va le mettre en place dans la foulée :
grails-app/conf/SecurityConfig.groovy
security {
active = true
loginUserDomainClass = "fr.xebia.bookstore.security.User"
authorityDomainClass = "fr.xebia.bookstore.security.Role"
requestMapClass = "fr.xebia.bookstore.security.RequestMap"
defaultRole = 'ROLE_USER' // Role par defaut des nouveaux utilisateurs
useMail = true // specifie d'envoyer un mail à l'enregistrement d'un compte
mailHost = 'localhost' // serveur d'envoi de mails
mailProtocol = 'smtp' // nom du protocole JavaMail
mailFrom = 'no.reply@bookstore.fr' // adresse de l'envoyeur du mail
mailPort = 25 // port de connexion au serveur de mail
}
Avec ces modifications, tous les internautes qui créeront des comptes par le formulaire obtiendrons le rôle ROLE_USER et recevront un mail comme ceci :

Si vous souhaitez adapter un peu le format du mail, le code associé est situé vers la ligne 170 du code de RegisterController :
extrait de grails-app/controllers/RegisterController.groovy
[...]
if (config.security.useMail) {
String emailContent = """You have signed up for an account at:
${request.scheme}://${request.serverName}:${request.serverPort}${request.contextPath}
Here are the details of your account:
-------------------------------------
LoginName: ${person.username}
Email: ${person.email}
Full Name: ${person.userRealName}
Password: ${params.passwd}
"""
def email = [
to: [person.email], // 'to' expects a List, NOT a single email address
subject: "[${request.contextPath}] Account Signed Up",
text: emailContent // 'text' is the email body
]
emailerService.sendEmails([email])
}
[...]
Et voilà comment en quelques minutes on peut avoir une application, basique certes… mais sécurisée !
Le plugin Grails Spring Security possède de nombreuses autres options. Je n’ai développé ici que la stratégie de stockage des règles de sécurité dans la base, mais il est également possible de les définir directement dans le fichier SecurityConfig, ou par annotations des méthodes des contrôleurs.
On peut appuyer la sécurité sur OpenID, LDAP, CAS, NTLM ou même utiliser une connexion FaceBook Connect. On peut changer l’algorithme de cryptage des mots de passe, les possibilités sont assez étendues.
Et si vraiment Spring Security ne vous convient pas, il existe d’autres solutions de sécurité à base de plugins comme Shiro ou Stark, qui feront peut-être l’objet d’autres articles dans le futur.
L’utilisation du plugin Grails Spring Security permet de mettre le pied à l’étrier très rapidement, en s’appuyant sur un standard des frameworks de sécurité en Java. J’ai personnellement beaucoup apprécié la simplicité de prise en main et les exemples fournis dans la documentation officielle. Je vous invite d’ailleurs à la parcourir, elle contient d’autres tutoriels notamment pour l’utilisation de OpenID et LDAP.
Nota Bene : Cet article est fortement inspiré de celui-ci, mais il méritait des précisions à mon goût.
Ressources :
Article printed from Blog Xebia France: http://blog.xebia.fr
URL to article: http://blog.xebia.fr/2010/02/25/grails-spring-security-plugin-la-securite-facile/
Click here to print.