This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch gh-pages
in repository https://gitbox.apache.org/repos/asf/grails-spring-security.git
The following commit(s) were added to refs/heads/gh-pages by this push:
new 108079546 Deploying to documentation branch - 02:20:29
108079546 is described below
commit 108079546586c4e83a7098845f6bcb304ec25db1
Author: jamesfredley <[email protected]>
AuthorDate: Thu Feb 19 02:20:29 2026 +0000
Deploying to documentation branch - 02:20:29
---
snapshot/acl-plugin/guide/index.html | 2 +-
snapshot/cas-plugin/guide/index.html | 2 +-
snapshot/core-plugin/guide/index.html | 84 ++++++++++++++++++++++++++++++++-
snapshot/ldap-plugin/guide/index.html | 2 +-
snapshot/oauth2-plugin/guide/index.html | 2 +-
snapshot/rest-plugin/guide/index.html | 2 +-
snapshot/ui-plugin/guide/index.html | 2 +-
7 files changed, 89 insertions(+), 7 deletions(-)
diff --git a/snapshot/acl-plugin/guide/index.html
b/snapshot/acl-plugin/guide/index.html
index abf7bf073..b2a797f9f 100644
--- a/snapshot/acl-plugin/guide/index.html
+++ b/snapshot/acl-plugin/guide/index.html
@@ -2534,7 +2534,7 @@ the body content
<div id="footer">
<div id="footer-text">
Version 7.0.2-SNAPSHOT<br>
-Last updated 2026-02-19 02:04:10 UTC
+Last updated 2026-02-19 02:17:33 UTC
</div>
</div>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/run_prettify.min.js"></script>
diff --git a/snapshot/cas-plugin/guide/index.html
b/snapshot/cas-plugin/guide/index.html
index bba11f204..a09f20124 100644
--- a/snapshot/cas-plugin/guide/index.html
+++ b/snapshot/cas-plugin/guide/index.html
@@ -814,7 +814,7 @@ body.book #toc,body.book #preamble,body.book
h1.sect0,body.book .sect1>h2{page-b
<div id="footer">
<div id="footer-text">
Version 7.0.2-SNAPSHOT<br>
-Last updated 2026-02-19 02:04:10 UTC
+Last updated 2026-02-19 02:17:33 UTC
</div>
</div>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/run_prettify.min.js"></script>
diff --git a/snapshot/core-plugin/guide/index.html
b/snapshot/core-plugin/guide/index.html
index 0a7066cd4..40673837a 100644
--- a/snapshot/core-plugin/guide/index.html
+++ b/snapshot/core-plugin/guide/index.html
@@ -6617,12 +6617,27 @@ class User implements Serializable {
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
+If you use this older pattern, be aware that
<code>springSecurityService</code> will be <code>null</code> when creating User
instances in <code>BootStrap.groovy</code>. Domain class instances are plain
Groovy objects, not Spring-managed beans, so their transient service references
are not autowired at construction time. The <code>beforeInsert()</code>
callback will silently skip password encoding because of the <code>?.</code>
safe-navigation operator, resulting in plaintext passwords st [...]
+</td>
+</tr>
+</table>
+</div>
+<div class="admonitionblock warning">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-warning" title="Warning"></i>
+</td>
+<td class="content">
Service injection in GORM entities is disabled by default since Grails 3.2.8.
Read documentation about <a
href="https://docs.grails.org/latest/ref/Domain%20Classes/Usage.html#_spring_autowiring_of_domain_instances">Spring
Autowiring of Domain Instances</a> to learn how to turn autowire on.
</td>
</tr>
</table>
</div>
<div class="paragraph">
+<p>Even with autowiring enabled, transient service references (such as
<code>springSecurityService</code>) are only injected into domain instances
that are loaded by GORM from the database. Freshly constructed instances (e.g.,
<code>new User(…​)</code>) are plain Groovy objects and will have
<code>null</code> for all transient service fields. This is particularly
important in <code>BootStrap.groovy</code>, where newly created domain
instances will not have <code>springSecurit [...]
+</div>
+<div class="paragraph">
<p><code>s2-quickstart</code> script generates this Role too:</p>
</div>
<div class="listingblock">
@@ -6864,8 +6879,75 @@ class BootStrap {
<li>
<p>We explicitly flush (using <code>withSession</code>) because
<code>BootStrap</code> does not run in a transaction or OpenSessionInView.</p>
</li>
+<li>
+<p>This example works correctly because the
<code>UserPasswordEncoderListener</code> (a Spring-managed bean) handles
password encoding during the GORM <code>PreInsertEvent</code>. If you are using
the older domain class pattern with <code>beforeInsert()</code> instead, see
the note below.</p>
+</li>
</ul>
</div>
+<div class="sect4">
+<h5 id="bootstrapPasswordEncoding">Password Encoding in BootStrap</h5>
+<div class="paragraph">
+<p>If you are using the older User domain class pattern where
<code>springSecurityService</code> is declared as a <code>transient</code>
field and password encoding happens in <code>beforeInsert()</code>, passwords
will <strong>not</strong> be encoded when creating users in
<code>BootStrap.groovy</code>. This is because domain class instances are plain
Groovy objects - their transient service references are not autowired by Spring
at construction time. The <code>springSecurityService</co [...]
+</div>
+<div class="paragraph">
+<p>To work around this, inject the <code>passwordEncoder</code> bean directly
in <code>BootStrap</code> and pre-encode passwords before saving:</p>
+</div>
+<div class="listingblock">
+<div class="title"><code>BootStrap.groovy</code></div>
+<div class="content">
+<pre class="prettyprint highlight"><code data-lang="groovy">import
grails.gorm.transactions.Transactional
+import org.springframework.security.crypto.password.PasswordEncoder
+
+class BootStrap {
+
+ PasswordEncoder passwordEncoder <i class="conum"
data-value="1"></i><b>(1)</b>
+
+ def init = {
+ addTestUser()
+ }
+
+ @Transactional
+ void addTestUser() {
+ def adminRole = new Role(authority: 'ROLE_ADMIN').save()
+
+ String encodedPassword = passwordEncoder.encode('password') <i
class="conum" data-value="2"></i><b>(2)</b>
+ def testUser = new User(username: 'me', password:
encodedPassword).save()
+
+ UserRole.create testUser, adminRole
+
+ UserRole.withSession {
+ it.flush()
+ it.clear()
+ }
+ }
+}</code></pre>
+</div>
+</div>
+<div class="colist arabic">
+<table>
+<tr>
+<td><i class="conum" data-value="1"></i><b>1</b></td>
+<td>The <code>PasswordEncoder</code> bean is auto-configured by the plugin and
can be injected into <code>BootStrap</code> by name.</td>
+</tr>
+<tr>
+<td><i class="conum" data-value="2"></i><b>2</b></td>
+<td>Pre-encode the password before constructing the <code>User</code> instance
so that password encoding is handled explicitly here, rather than relying on a
<code>beforeInsert()</code> hook or an injected
<code>springSecurityService</code> in the domain class.</td>
+</tr>
+</table>
+</div>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+Be careful not to double-encode passwords if you also use a
<code>beforeInsert()</code>-style encoding hook or a Spring-managed listener
(for example, a <code>User</code> domain class with an injected
<code>springSecurityService</code>, or a
<code>UserPasswordEncoderListener</code> that encodes on insert/update). In
those cases, the callback or listener would see the already-encoded value
produced in <code>BootStrap</code> and attempt to encode it again. Ensure that
only one mechanism is [...]
+</td>
+</tr>
+</table>
+</div>
+</div>
</div>
<div class="sect3">
<h4 id="6-start-the-server">22.1.6. 6. Start the server.</h4>
@@ -7389,7 +7471,7 @@ logger 'grails.plugin.springsecurity', DEBUG, ['STDOUT'],
false</code></pre>
<div id="footer">
<div id="footer-text">
Version 7.0.2-SNAPSHOT<br>
-Last updated 2026-02-19 02:04:10 UTC
+Last updated 2026-02-19 02:17:33 UTC
</div>
</div>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/run_prettify.min.js"></script>
diff --git a/snapshot/ldap-plugin/guide/index.html
b/snapshot/ldap-plugin/guide/index.html
index 14d649eba..cec82dea2 100644
--- a/snapshot/ldap-plugin/guide/index.html
+++ b/snapshot/ldap-plugin/guide/index.html
@@ -1191,7 +1191,7 @@ beans = {
<div id="footer">
<div id="footer-text">
Version 7.0.2-SNAPSHOT<br>
-Last updated 2026-02-19 02:04:10 UTC
+Last updated 2026-02-19 02:17:33 UTC
</div>
</div>
</body>
diff --git a/snapshot/oauth2-plugin/guide/index.html
b/snapshot/oauth2-plugin/guide/index.html
index e128e6a41..d06656c96 100644
--- a/snapshot/oauth2-plugin/guide/index.html
+++ b/snapshot/oauth2-plugin/guide/index.html
@@ -915,7 +915,7 @@ protected void authenticateAndRedirect(OAuth2SpringToken
oAuthToken, redirectUrl
<div id="footer">
<div id="footer-text">
Version 7.0.2-SNAPSHOT<br>
-Last updated 2026-02-19 02:04:10 UTC
+Last updated 2026-02-19 02:17:33 UTC
</div>
</div>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/run_prettify.min.js"></script>
diff --git a/snapshot/rest-plugin/guide/index.html
b/snapshot/rest-plugin/guide/index.html
index 8dfb81321..0c2d6b3c7 100644
--- a/snapshot/rest-plugin/guide/index.html
+++ b/snapshot/rest-plugin/guide/index.html
@@ -3747,7 +3747,7 @@ way of using HTTP sessions. So not acceptable.</p>
<div id="footer">
<div id="footer-text">
Version 7.0.2-SNAPSHOT<br>
-Last updated 2026-02-19 02:04:10 UTC
+Last updated 2026-02-19 02:17:33 UTC
</div>
</div>
</body>
diff --git a/snapshot/ui-plugin/guide/index.html
b/snapshot/ui-plugin/guide/index.html
index 646591770..ac0dce458 100644
--- a/snapshot/ui-plugin/guide/index.html
+++ b/snapshot/ui-plugin/guide/index.html
@@ -2499,7 +2499,7 @@ The second service is a listener service which ensures
that anytime an answer is
<div id="footer">
<div id="footer-text">
Version 7.0.2-SNAPSHOT<br>
-Last updated 2026-02-19 02:04:10 UTC
+Last updated 2026-02-19 02:17:33 UTC
</div>
</div>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/run_prettify.min.js"></script>