2 Differences Between the Spring Security and Acegi Plugins
The Spring Security plugin is a successor to the Acegi plugin. The sections that follow compare the two.
Core Similarities and Differences
The Spring Security plugin retains many core features of the Acegi plugin:
- 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
- Security tags
- Security service
- Security events
- Ajax login
- Basic authentication
- Switch User
- Channel security
- IP address restrictions
and adds several new features:
- Digest authentication
- Session Fixation Prevention
- Salted passwords
- Certificate (x509) login
- Hierarchical roles
- Account locking and forcing password change
Features Not Included in the Spring Security Plugin
The following features are not included in the Spring Security plugin, but are (or will be) available in secondary plugins that extend and depend on the core plugin:
To initialize the Acegi plugin, you run
create-auth-domains. This initialization creates
grails-app/conf/SecurityConfig.groovy to allow configuration customization; creates the User, Role, and Requestmap domain classes; and creates the Login and Logout controllers and views. Another Acegi script,
generate-manager, creates CRUD pages for the domain classes. (The earlier version of Grails did not scaffold many-to-many relationships well, so these GSPs were necessary.)In addition, a
generate-registration script installs a basic user registration controller.
The Spring Security plugin uses only one script, s2-quickstart. It is similar to
create-auth-domains because it creates domain classes and login and logout bcontrollers, but it appends files to
grails-app/conf/Config.groovy instead of creating a standalone configuration file. There is no equivalent to
generate-registration because an optional UI plugin generates domain class management screens, an admin console, and forgot password and registration workflows. If you want to create your own CRUD pages, you can use the standard Grails
generate-allscript. Various sections of this documentation discuss required changes to the generated source files, for example, encrypting passwords before saving or updating a user.
The Acegi plugin extends the
UserDetails instance and adds an accessor for the person domain class instance that is used to populate the
UserDetails. Because the
Authentication is kept in the HTTP session and the
UserDetails is attached to that, it is easy to access non-security data such as full name, email, and so on without hitting the database.
However, with this approach, if the domain class has a lot of data, you increase the size of the session payload, which is exacerbated by clustered sessions. Further, any lazy-loaded collections fail to load after retrieving the person from the session because it would have become a detached Hibernate object. This problem is addressed by a call to
person.attach() or by reloading by id, for example:
def userDetails = authenticateService.principal() def person = userDetails.domainClass person = Person.get(person.id)
But with this approach, the person class is essentially a very large wrapper around its primary key since that’s the real data you’re storing.
To resolve this issue, the Spring Security plugin does not store the domain class but instead stores the id so you can retrieve the person easily:
def userDetails = springSecurityService.principal person = Person.get(userDetails.id)
The preceding approach works because the
UserDetails implementation is an instance of
org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser, which extends the standard Spring Security User and adds a
You can further extend this class if you want to store more data along with the authentication to avoid database access. See Custom UserDetailsService.