Grails 6 Spring Security Core Login Tutorial

by Didin J. on May 27, 2025 Grails 6 Spring Security Core Login Tutorial

Learn how to implement a secure login system in Grails 6 using Spring Security Core with step-by-step configuration and authentication setup

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.

Grails 6 Spring Security Core Login Tutorial - grails home


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.

Grails 6 Spring Security Core Login Tutorial - login

Grails 6 Spring Security Core Login Tutorial - dashboard


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:

Thanks!