Certains d’entre vous ont peut-être déjà constaté la grande simplicité de mise en place de Spring Security dans une application Grails (si ce n’est pas le cas, je vous invite à lire l’article Grails Spring Security, la sécurité facile publiée par Aurélien Maury sur le sujet).
Depuis cet article, les développements du plugin Acegi ont été arrêtés, au profit du plugin officiel Spring Security Core. Voici donc un petit tutoriel mis à jour, pour installer une gestion des utilisateurs, avec gestion des rôles, filtres URL/Rôles avec le plugin Spring Security Core. Cela servira de base pour la suite de l’article Facebook Connect avec Grails qui traitera le sujet de l’intégration de Facebook Connect avec Spring Security dans Grails.
Cet article s’adresse aux personnes ayant déjà une expérience autour du framework Grails. Pour les autres, je vous invite vivement à lire la série d’articles NoThunes, naissances d’un projet Grails publiée par Aurélien Maury.
Note technique
L’exemple est réalisé avec Grails v1.3.7.
Pour démarrer
Nous 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 grails create-domain-class fr.xebia.bookstore.domain.Book
Nous éditons ensuite la classe Book pour y ajouter quelques attributs :
package fr.xebia.bookstore.domain class Book { String title String author static constraints = { title(nullable:false) author(nullable:false) } }
Nous générons le CRUD pour la gestion des Books :
grails generate-all fr.xebia.bookstore.domain.Book
Maintenant, Nous passons à l’installation du plugin Spring Security Core :
grails install-plugin spring-security-core
Pour la gestion de la sécurité, des utilisateurs et des rôles, le plugin fournit le script s2-quickstart pour générer les classes du domaine, les contrôleurs et les vues associés.
grails s2-quickstart fr.xebia.bookstore.security User Role
L’exécution de la commande s2-quickstart ajoute le mapping entre les classes générées et Spring Security dans le fichier Config.groovy.
grails.plugins.springsecurity.userLookup.userDomainClassName = 'fr.xebia.bookstore.security.User' grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'fr.xebia.bookstore.security.UserRole' grails.plugins.springsecurity.authority.className = 'fr.xebia.bookstore.security.Role'
Nous générons également les CRUD pour les classes User, Role et UserRole (classe générée par le plugin pour attribuer des rôles à un utilisateur donné).
grails generate-all fr.xebia.bookstore.security.User grails generate-all fr.xebia.bookstore.security.Role grails generate-all fr.xebia.bookstore.security.UserRole
A ce stade, nous disposons des contrôleurs suivants (et des vues qui vont avec) :
- fr.xebia.bookstore.BookController : CRUD de gestion de la classe Book
- LoginController : Contrôleur de connexion
- LogoutController : Contrôleur de déconnexion
- RoleController : CRUD de gestion des rôles
- UserController : CRUD de gestion des utilisateurs dans l’espace d’administration
- UserRoleController : CRUD d’attribution des rôles à un utilisateur donné
On peut déjà démarrer l’application avec un grails run-app et voir ce que ça donne :
Configuration et sécurisation
Maintenant que nous disposons des briques nécessaires pour sécuriser notre application. Nous procédons à la sécurisation des écrans de l’application en définissant des règles de sécurité sur les URLs avec les différents rôles autorisés à y accéder.
- La liste des books est accessible par tout le monde.
- La gestion des books est accessible aux utilisateurs avec les rôles ROLE_USER et ROLE_ADMIN
- La gestion des utilisateurs, des rôles et des règles de sécurité est limitée au rôle ROLE_ADMIN
Pour la suite, nous avons besoin de configurer les règles de sécurité sur les URLs. Plusieurs stratégies de stockage des règles de sécurité existent (dans la base avec RequestMap, dans le fichier de configuration Config.groovy, ou par annotations sur les méthodes des contrôleurs). Dans cet exemple, on va se contenter de la mise à jour du fichier de configuration.
Dans BookStore/grails-app/conf/Config.groovy :
grails.plugins.springsecurity.securityConfigType = "InterceptUrlMap" grails.plugins.springsecurity.interceptUrlMap = [ '/book/create/**': ['ROLE_ADMIN','ROLE_USER'], '/user/**' : ['ROLE_ADMIN'], '/role/**' : ['ROLE_ADMIN'], '/userRole/**' : ['ROLE_ADMIN'] ]
Par défaut, une application Grails utilise HSQLDB et démarre avec une base vierge à chaque lancement. Nous allons initialiser les rôles par défaut, et un compte administrateur pour tester le fonctionnement de l’application.
Dans grails-app/conf/BootStrap.groovy :
import fr.xebia.security.Role import fr.xebia.security.User import fr.xebia.security.UserRole class BootStrap { def init = { servletContext -> def roleAdmin = new Role(authority: 'ROLE_ADMIN').save() def roleUser = new Role(authority: 'ROLE_USER').save() def userAdmin = new User(username: 'admin', password: 'admin', enabled: true) userAdmin.save() UserRole.create(userAdmin, roleAdmin) } def destroy = { } }
Maintenant que les règles des gestion de sécurité sont en place. Nous allons jouer quelques scénarios pour valider notre travail.
Création d’un nouvel utilisateur
![]() |
![]() |
![]() |
![]() |
Création d’un nouveau book
![]() |
![]() |
![]() |
![]() |
![]() |
Consultation de la liste des books
![]() |
![]() |
Quelles différences avec le plugin Acegi
Le plugin Spring Security Core est présenté comme le successeur du plugin Acegi. Le plugin Spring Security Core présente plusieurs similitudes avec son frère ainé. Nous trouvons une grande partie des fonctions de base du plugin Acegi, nous en citons quelques unes sans rentrer dans les détails :
- Form-based authentication
- Storing users, roles, and optionally requestmaps in the database, with access through domain classes
- Guarding URLs with annotations, requestmap domain class, or static configuration
- Basic authentication
- Ajax login
- Switch User
- IP address restrictions
…
D’autres fonctions viennent enrichir le plugin dont :
- Digest authentication
- Session Fixation Prevention
- Salted passwords
- Certificate (x509) login
- Hierarchical roles
- Account locking and forcing password change
…
L’étendue du plugin Spring Security Core ne se limite pas aux fonctions citées ci-dessus. Le plugin Spring Security Core possède de nombreuses autres options que nous ne pouvons citer dans un seul article. Nous nous sommes penchés ici uniquement sur les quelques fonctions de base pour démarrer sans douleurs.
Contrairement à son frère ainé, la sécurité sur OpenID, lDAP, CAS, Kerberos ou Facebook Connect, Twitter, User Registration … est gérée par des (sous) plugins que vous pouvez installer au besoin.
Toutefois, nous regrettons la suppression des fonctions generate-manager et generate-registration intégrés par défaut dans le plugin Acegi. Un sous plugin portant le nom de Spring Security UI couvre ses besoins. Mais en testant rapidement ce plugin nous avons un retour plutôt négatif. Reste à creuser le sujet pour aller plus loin dans l’analyse et confirmer ou infirmer ce retour.
Conclusion
L’utilisation du plugin Spring Security Core permet de gagner en productivité et définir la base nécessaire pour un démarrage rapide. Nous n’avons pas de retour d’expérience sur son utilisation sur de vrais projets mais nous restons convaincus de son efficacité et de sa fiabilité. Nous étions brefs sur la présentation des fonctionnalités et des étendues du plugin, mais nous vous invitons vivement à consulter la documentation officielle qui ne manque pas de tutoriels pour bien approfondir le sujet.
Ressources :