In this comprehensive Grails tutorial, you’ll learn how to implement a secure login system using the Spring Security Core plugin in a modern Grails 6 application. This guide walks you through the steps to integrate authentication, configure users and roles, and secure your Grails app using proven security practices.
Grails 6 brings updated support for Spring Boot 3, Java 17, and Micronaut-based features, making it more powerful and flexible than ever. Whether you’re building a new application or upgrading an older one, this tutorial will help you set up a working login system from scratch with clear, updated steps for 2024 and beyond.
Create a New Grails 6 Application
To begin, make sure you have Java 17+ and the Grails 6 CLI installed.
Install Grails 6 CLI (if not already)
If you haven’t installed Grails yet, you can do so with SDKMAN:
sdk install grails 6.2.3
You can also verify the version:
grails -version
Expected output:
Grails Version: 6.2.3
JVM Version: 17.0.9
Create a New Grails 6 App
Now create a new Grails application:
grails create-app grails6-secure-login
Change into the project directory:
cd grails6-secure-login
Start the development server to confirm it works:
./gradlew bootRun
Then visit http://localhost:8080 in your browser to confirm that the Grails welcome page appears.
Installing and Configuring Spring Security Core
To add user authentication and authorization, we’ll use the Spring Security Core plugin, which provides a complete security framework for Grails.
Step 1: Add the Plugin
Open the build.gradle
file and add the following plugin to the dependencies section:
dependencies {
implementation 'org.grails.plugins:spring-security-core:6.0.0'
}
✅ Note: You can check for the latest version at https://plugins.grails.org/plugin/grails/spring-security-core
Then refresh your Gradle dependencies:
./gradlew clean build
Step 2: Generate Security Artifacts
Use the Grails CLI to generate domain classes and config for Spring Security:
./gradlew runCommand "-Pargs=s2-quickstart com.djamware.auth User Role"
This will generate:
-
User.groovy
– user domain class -
Role.groovy
– role domain class -
UserRole.groovy
– join the table class -
Security-related config in
application.groovy
Step 3: Verify Domain Classes
Generated domain classes will be under grails-app/domain/com/djamware/auth/
. Here's what the User.groovy
class looks like by default:
package com.djamware.auth
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import grails.compiler.GrailsCompileStatic
@GrailsCompileStatic
@EqualsAndHashCode(includes='username')
@ToString(includes='username', includeNames=true, includePackage=false)
class User implements Serializable {
private static final long serialVersionUID = 1
String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
Set<Role> getAuthorities() {
(UserRole.findAllByUser(this) as List<UserRole>)*.role as Set<Role>
}
static constraints = {
password nullable: false, blank: false, password: true
username nullable: false, blank: false, unique: true
}
static mapping = {
table name: '`user`'
password column: '`password`'
}
}
Creating Controllers and Securing Routes
With the security domain classes in place, it’s time to create a basic controller and configure route access using Spring Security.
Step 1: Create a Secure Controller
Let’s generate a simple controller that requires authentication to access:
grails create-controller com.djamware.secure.Dashboard
Open DashboardController.groovy
and update it like this:
package com.djamware.secure
import grails.plugin.springsecurity.annotation.Secured
import grails.plugin.springsecurity.SpringSecurityService
@Secured(['ROLE_USER'])
class DashboardController {
SpringSecurityService springSecurityService
def index() {
def username = springSecurityService?.currentUser?.username ?: 'Guest'
[username: username]
}
}
Now create a basic view at grails-app/views/dashboard/index.gsp
:
<!DOCTYPE html>
<html>
<head>
<title>Dashboard</title>
</head>
<body>
<h1>Welcome to the Secure Dashboard!</h1>
<p>You are logged in as <strong>${username}</strong></p>
<g:link controller="logout">Logout</g:link>
</body>
</html>
Step 2: Update application.groovy
Security Rules
Open grails-app/conf/application.groovy
and configure static security rules:
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
[pattern: '/', access: ['permitAll']],
[pattern: '/error', access: ['permitAll']],
[pattern: '/index', access: ['permitAll']],
[pattern: '/shutdown', access: ['permitAll']],
[pattern: '/assets/**', access: ['permitAll']],
[pattern: '/**/favicon.ico', access: ['permitAll']],
[pattern: '/dashboard/**', access: ['ROLE_USER']]
]
You can also redirect the default login success to the dashboard by adding:
grails.plugin.springsecurity.successHandler.defaultTargetUrl = '/dashboard'
Step 3: Create a Test User
Add a test user and role using BootStrap.groovy
For demo purposes:
import com.djamware.auth.*
class BootStrap {
def init = { servletContext ->
User.withTransaction {
def userRole = Role.findOrSaveWhere(authority: 'ROLE_USER')
def user = User.findOrSaveWhere(username: 'admin')
user.password = 'password' // Will be encoded by Spring Security
user.save(flush: true)
if (!UserRole.exists(user.id, userRole.id)) {
UserRole.create(user, userRole, true)
}
}
}
def destroy = {}
}
You can now start the server and visit http://localhost:8080/dashboard. You should be prompted to log in using admin
/ password
.
Customizing the Login and Logout Views
By default, Spring Security Core in Grails provides built-in login and logout pages. However, to give your application a polished and branded experience, you can override these views and use your own.
1. Create the login
View Folder
Create the following folder if it doesn't exist:
grails-app/views/login/
2. Create auth.gsp
Inside that folder, create a file named auth.gsp
. This is your custom login page.
Example: grails-app/views/login/auth.gsp
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main"/>
<title>Login</title>
</head>
<body>
<h2>Login</h2>
<g:if test='${flash.message}'>
<div class="alert alert-danger">${flash.message}</div>
</g:if>
<form action='${postUrl}' method='POST'>
<div>
<label for="username">Username:</label>
<input type='text' name='username' id='username' />
</div>
<div>
<label for="password">Password:</label>
<input type='password' name='password' id='password' />
</div>
<div>
<input type='submit' value='Login'/>
</div>
</form>
</body>
</html>
The the ${postUrl}
variable is provided by the plugin to point to the login processing endpoint.
3. Optional: Create Additional Views
You can also create the following GSPs as needed:
-
authfail.gsp
→ shown on login failure -
denied.gsp
→ shown when access is denied -
loggedout.gsp
→ shown after logout
Create them in the same folder with minimal content or styled messages.
4. Customize Logout
By default, logout works by visiting the /logout
URL. If you want to add a logout button or link in your UI:
<g:link controller="logout">Logout</g:link>
Or use a form-based logout if you prefer a POST request:
<form action="${createLink(controller:'logout')}" method="POST">
<input type="submit" value="Logout"/>
</form>
5. Optional: Change the Login URL
If you want to use a custom login URL (e.g., /login
instead of /login/auth
You can configure it in application.yml
:
grails:
plugin:
springsecurity:
auth:
loginFormUrl: /login
Conclusion
In this Grails 6 tutorial, we walked through the process of implementing a secure login system using the Spring Security Core plugin. You learned how to set up and configure the plugin, define secure URL access rules, create user and role domains, and build custom login and logout pages. With Grails 6’s enhancements and the plugin’s robust security features, you can now easily extend this foundation to support role-based authorization, remember-me functionality, or OAuth integrations.
This setup provides a solid starting point for building enterprise-grade Grails applications with modern security standards. As next steps, consider adding user registration, password reset features, and more advanced security controls to enhance your app’s authentication system.
You can find the full working source code on our GitHub.
That's just the basics. If you need more deep learning about Groovy and Grails, you can take the following cheap course:
- Mastering Grails. A Comprehensive Grails Course.
- Groovy Scripting for Developers / Testers
- Introduction to JVM Languages: Clojure, Kotlin, and Groovy
Thanks!