This is an automated email from the ASF dual-hosted git repository.
asf-ci-deploy pushed a commit to branch asf-site-production
in repository https://gitbox.apache.org/repos/asf/grails-website.git
The following commit(s) were added to refs/heads/asf-site-production by this
push:
new 1efb34946df Deploying to documentation branch - 11:25:29
1efb34946df is described below
commit 1efb34946df74e5501c0c66390c00bb585b0d5cd
Author: sbglasius <[email protected]>
AuthorDate: Fri Aug 21 11:25:33 2026 +0000
Deploying to documentation branch - 11:25:29
---
.../cas/SpringSecurityCasGrailsPlugin.html | 29 +-----
docs/snapshot/api/index-all.html | 4 -
.../developer-manual/gettingStarted.html | 2 +-
.../grails-data/developer-manual/introduction.html | 2 +-
.../grails-data/developer-manual/stepByStep.html | 2 +-
.../grails-data/developer-manual/testing.html | 2 +-
.../developer-manual/understandingApi.html | 2 +-
.../understandingApi/datastoreBasics.html | 2 +-
.../understandingApi/gormApis.html | 2 +-
.../understandingApi/gormEnhancer.html | 2 +-
.../understandingApi/implementingCrud.html | 2 +-
.../understandingApi/implementingQueries.html | 2 +-
.../understandingApi/secondaryIndexes.html | 2 +-
.../grails-data/whats-new-manual/index.html | 2 +-
docs/snapshot/guide/security.html | 71 ++++++++++---
docs/snapshot/guide/single.html | 111 ++++++++++++++++++---
docs/snapshot/guide/upgrading.html | 40 ++++++++
17 files changed, 212 insertions(+), 67 deletions(-)
diff --git
a/docs/snapshot/api/grails/plugin/springsecurity/cas/SpringSecurityCasGrailsPlugin.html
b/docs/snapshot/api/grails/plugin/springsecurity/cas/SpringSecurityCasGrailsPlugin.html
index b7863ec7400..55b3495db92 100644
---
a/docs/snapshot/api/grails/plugin/springsecurity/cas/SpringSecurityCasGrailsPlugin.html
+++
b/docs/snapshot/api/grails/plugin/springsecurity/cas/SpringSecurityCasGrailsPlugin.html
@@ -101,7 +101,8 @@ if (location.href.indexOf('is-external=true') == -1) {
<!-- todo: direct known subclasses -->
<hr>
-<pre>@groovy.transform.CompileStatic
+<pre>@groovy.util.logging.Slf4j
[email protected]
class SpringSecurityCasGrailsPlugin
extends <a href='../../../../grails/plugins/Plugin.html'>Plugin</a></pre>
@@ -153,16 +154,6 @@ extends <a
href='../../../../grails/plugins/Plugin.html'>Plugin</a></pre>
<th class="colLast" scope="col">Name and
description</th>
</tr>
- <tr class="altColor">
- <td
class="colFirst"><code><strong>java.lang.String</strong></code> </td>
- <td class="colLast"><code><a
href="#author">author</a></code><br></td>
- </tr>
-
- <tr class="rowColor">
- <td
class="colFirst"><code><strong>java.lang.String</strong></code> </td>
- <td class="colLast"><code><a
href="#authorEmail">authorEmail</a></code><br></td>
- </tr>
-
<tr class="altColor">
<td
class="colFirst"><code><strong>java.lang.String</strong></code> </td>
<td class="colLast"><code><a
href="#description">description</a></code><br></td>
@@ -327,22 +318,6 @@ extends <a
href='../../../../grails/plugins/Plugin.html'>Plugin</a></pre>
</a>
<h3>Property Detail</h3>
- <a name="author"><!-- --></a>
- <ul class="blockListLast">
- <li class="blockList">
- <h4>java.lang.String
<strong>author</strong></h4>
- <p></p>
- </li>
- </ul>
-
- <a name="authorEmail"><!-- --></a>
- <ul class="blockListLast">
- <li class="blockList">
- <h4>java.lang.String
<strong>authorEmail</strong></h4>
- <p></p>
- </li>
- </ul>
-
<a name="description"><!-- --></a>
<ul class="blockListLast">
<li class="blockList">
diff --git a/docs/snapshot/api/index-all.html b/docs/snapshot/api/index-all.html
index c84201d4fcb..5db4662f2ab 100644
--- a/docs/snapshot/api/index-all.html
+++ b/docs/snapshot/api/index-all.html
@@ -3308,8 +3308,6 @@ if (location.href.indexOf('is-external=true') == -1) {
</dt><dd> <div class="block"></div></dd>
<dt><span class="strong"><a
href="grails/plugin/springsecurity/acl/SpringSecurityAclGrailsPlugin.html#author"
title="Property in SpringSecurityAclGrailsPlugin">author</a></span> - Property
in <a
href="grails/plugin/springsecurity/acl/SpringSecurityAclGrailsPlugin.html">SpringSecurityAclGrailsPlugin</a>
</dt><dd> <div class="block"></div></dd>
-<dt><span class="strong"><a
href="grails/plugin/springsecurity/cas/SpringSecurityCasGrailsPlugin.html#author"
title="Property in SpringSecurityCasGrailsPlugin">author</a></span> - Property
in <a
href="grails/plugin/springsecurity/cas/SpringSecurityCasGrailsPlugin.html">SpringSecurityCasGrailsPlugin</a>
-</dt><dd> <div class="block"></div></dd>
<dt><span class="strong"><a
href="grails/plugin/springsecurity/SpringSecurityCoreGrailsPlugin.html#author"
title="Property in SpringSecurityCoreGrailsPlugin">author</a></span> - Property
in <a
href="grails/plugin/springsecurity/SpringSecurityCoreGrailsPlugin.html">SpringSecurityCoreGrailsPlugin</a>
</dt><dd> <div class="block"></div></dd>
<dt><span class="strong"><a
href="grails/plugin/springsecurity/ldap/SpringSecurityLdapGrailsPlugin.html#author"
title="Property in SpringSecurityLdapGrailsPlugin">author</a></span> -
Property in <a
href="grails/plugin/springsecurity/ldap/SpringSecurityLdapGrailsPlugin.html">SpringSecurityLdapGrailsPlugin</a>
@@ -3352,8 +3350,6 @@ if (location.href.indexOf('is-external=true') == -1) {
</dt><dd> <div class="block"></div></dd>
<dt><span class="strong"><a
href="grails/plugin/springsecurity/acl/SpringSecurityAclGrailsPlugin.html#authorEmail"
title="Property in SpringSecurityAclGrailsPlugin">authorEmail</a></span> -
Property in <a
href="grails/plugin/springsecurity/acl/SpringSecurityAclGrailsPlugin.html">SpringSecurityAclGrailsPlugin</a>
</dt><dd> <div class="block"></div></dd>
-<dt><span class="strong"><a
href="grails/plugin/springsecurity/cas/SpringSecurityCasGrailsPlugin.html#authorEmail"
title="Property in SpringSecurityCasGrailsPlugin">authorEmail</a></span> -
Property in <a
href="grails/plugin/springsecurity/cas/SpringSecurityCasGrailsPlugin.html">SpringSecurityCasGrailsPlugin</a>
-</dt><dd> <div class="block"></div></dd>
<dt><span class="strong"><a
href="grails/plugin/springsecurity/SpringSecurityCoreGrailsPlugin.html#authorEmail"
title="Property in SpringSecurityCoreGrailsPlugin">authorEmail</a></span> -
Property in <a
href="grails/plugin/springsecurity/SpringSecurityCoreGrailsPlugin.html">SpringSecurityCoreGrailsPlugin</a>
</dt><dd> <div class="block"></div></dd>
<dt><span class="strong"><a
href="grails/plugin/springsecurity/ldap/SpringSecurityLdapGrailsPlugin.html#authorEmail"
title="Property in SpringSecurityLdapGrailsPlugin">authorEmail</a></span> -
Property in <a
href="grails/plugin/springsecurity/ldap/SpringSecurityLdapGrailsPlugin.html">SpringSecurityLdapGrailsPlugin</a>
diff --git a/docs/snapshot/grails-data/developer-manual/gettingStarted.html
b/docs/snapshot/grails-data/developer-manual/gettingStarted.html
index 429568f9f7c..f89c0c36566 100644
--- a/docs/snapshot/grails-data/developer-manual/gettingStarted.html
+++ b/docs/snapshot/grails-data/developer-manual/gettingStarted.html
@@ -523,7 +523,7 @@ cd grails-core</pre>
<div id="footer">
<div id="footer-text">
Version 8.0.0-SNAPSHOT<br>
-Last updated 2026-08-20 23:44:26 UTC
+Last updated 2026-08-21 11:01:52 UTC
</div>
</div>
</body>
diff --git a/docs/snapshot/grails-data/developer-manual/introduction.html
b/docs/snapshot/grails-data/developer-manual/introduction.html
index ee36c6fd5e7..a636b8edfdc 100644
--- a/docs/snapshot/grails-data/developer-manual/introduction.html
+++ b/docs/snapshot/grails-data/developer-manual/introduction.html
@@ -476,7 +476,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 8.0.0-SNAPSHOT<br>
-Last updated 2026-08-20 23:44:26 UTC
+Last updated 2026-08-21 11:01:52 UTC
</div>
</div>
</body>
diff --git a/docs/snapshot/grails-data/developer-manual/stepByStep.html
b/docs/snapshot/grails-data/developer-manual/stepByStep.html
index 801221e11a6..e6d7c1367aa 100644
--- a/docs/snapshot/grails-data/developer-manual/stepByStep.html
+++ b/docs/snapshot/grails-data/developer-manual/stepByStep.html
@@ -621,7 +621,7 @@ class XyzTestSuite {
<div id="footer">
<div id="footer-text">
Version 8.0.0-SNAPSHOT<br>
-Last updated 2026-08-20 23:44:26 UTC
+Last updated 2026-08-21 11:01:52 UTC
</div>
</div>
</body>
diff --git a/docs/snapshot/grails-data/developer-manual/testing.html
b/docs/snapshot/grails-data/developer-manual/testing.html
index 16ebc897a6d..2cadd3c507d 100644
--- a/docs/snapshot/grails-data/developer-manual/testing.html
+++ b/docs/snapshot/grails-data/developer-manual/testing.html
@@ -511,7 +511,7 @@ class PagedResultSpec extends GormDatastoreSpec{
<div id="footer">
<div id="footer-text">
Version 8.0.0-SNAPSHOT<br>
-Last updated 2026-08-20 23:44:26 UTC
+Last updated 2026-08-21 11:01:52 UTC
</div>
</div>
</body>
diff --git a/docs/snapshot/grails-data/developer-manual/understandingApi.html
b/docs/snapshot/grails-data/developer-manual/understandingApi.html
index 438d1518abc..1b79c48ddcd 100644
--- a/docs/snapshot/grails-data/developer-manual/understandingApi.html
+++ b/docs/snapshot/grails-data/developer-manual/understandingApi.html
@@ -454,7 +454,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 8.0.0-SNAPSHOT<br>
-Last updated 2026-08-20 23:44:26 UTC
+Last updated 2026-08-21 11:01:52 UTC
</div>
</div>
</body>
diff --git
a/docs/snapshot/grails-data/developer-manual/understandingApi/datastoreBasics.html
b/docs/snapshot/grails-data/developer-manual/understandingApi/datastoreBasics.html
index cf3f262553b..6fbba3d92f5 100644
---
a/docs/snapshot/grails-data/developer-manual/understandingApi/datastoreBasics.html
+++
b/docs/snapshot/grails-data/developer-manual/understandingApi/datastoreBasics.html
@@ -561,7 +561,7 @@ protected Session createSession(PropertyResolver
connDetails) {
<div id="footer">
<div id="footer-text">
Version 8.0.0-SNAPSHOT<br>
-Last updated 2026-08-20 23:44:26 UTC
+Last updated 2026-08-21 11:01:52 UTC
</div>
</div>
</body>
diff --git
a/docs/snapshot/grails-data/developer-manual/understandingApi/gormApis.html
b/docs/snapshot/grails-data/developer-manual/understandingApi/gormApis.html
index 2fd244d04b4..352b68cef15 100644
--- a/docs/snapshot/grails-data/developer-manual/understandingApi/gormApis.html
+++ b/docs/snapshot/grails-data/developer-manual/understandingApi/gormApis.html
@@ -496,7 +496,7 @@ class Neo4jEntityTraitProvider implements
GormEntityTraitProvider {
<div id="footer">
<div id="footer-text">
Version 8.0.0-SNAPSHOT<br>
-Last updated 2026-08-20 23:44:26 UTC
+Last updated 2026-08-21 11:01:52 UTC
</div>
</div>
</body>
diff --git
a/docs/snapshot/grails-data/developer-manual/understandingApi/gormEnhancer.html
b/docs/snapshot/grails-data/developer-manual/understandingApi/gormEnhancer.html
index d235a6fbc3a..d27e1f5bd48 100644
---
a/docs/snapshot/grails-data/developer-manual/understandingApi/gormEnhancer.html
+++
b/docs/snapshot/grails-data/developer-manual/understandingApi/gormEnhancer.html
@@ -488,7 +488,7 @@ enhancer.enhance()</code></pre>
<div id="footer">
<div id="footer-text">
Version 8.0.0-SNAPSHOT<br>
-Last updated 2026-08-20 23:44:26 UTC
+Last updated 2026-08-21 11:01:52 UTC
</div>
</div>
</body>
diff --git
a/docs/snapshot/grails-data/developer-manual/understandingApi/implementingCrud.html
b/docs/snapshot/grails-data/developer-manual/understandingApi/implementingCrud.html
index 6c52ad38497..a07e0f8fac8 100644
---
a/docs/snapshot/grails-data/developer-manual/understandingApi/implementingCrud.html
+++
b/docs/snapshot/grails-data/developer-manual/understandingApi/implementingCrud.html
@@ -673,7 +673,7 @@ protected void deleteEntry(String family, final Object key,
final Object entry)
<div id="footer">
<div id="footer-text">
Version 8.0.0-SNAPSHOT<br>
-Last updated 2026-08-20 23:44:26 UTC
+Last updated 2026-08-21 11:01:52 UTC
</div>
</div>
</body>
diff --git
a/docs/snapshot/grails-data/developer-manual/understandingApi/implementingQueries.html
b/docs/snapshot/grails-data/developer-manual/understandingApi/implementingQueries.html
index 4a8d1b7fe4f..58f2b5d7c25 100644
---
a/docs/snapshot/grails-data/developer-manual/understandingApi/implementingQueries.html
+++
b/docs/snapshot/grails-data/developer-manual/understandingApi/implementingQueries.html
@@ -588,7 +588,7 @@ If, for instance, the underlying datastore does not support
the calculation of a
<div id="footer">
<div id="footer-text">
Version 8.0.0-SNAPSHOT<br>
-Last updated 2026-08-20 23:44:26 UTC
+Last updated 2026-08-21 11:01:52 UTC
</div>
</div>
</body>
diff --git
a/docs/snapshot/grails-data/developer-manual/understandingApi/secondaryIndexes.html
b/docs/snapshot/grails-data/developer-manual/understandingApi/secondaryIndexes.html
index 5c061e140a7..6e5b17cba65 100644
---
a/docs/snapshot/grails-data/developer-manual/understandingApi/secondaryIndexes.html
+++
b/docs/snapshot/grails-data/developer-manual/understandingApi/secondaryIndexes.html
@@ -526,7 +526,7 @@ If the underlying datastore supports secondary indexes then
it is ok to just ret
<div id="footer">
<div id="footer-text">
Version 8.0.0-SNAPSHOT<br>
-Last updated 2026-08-20 23:44:26 UTC
+Last updated 2026-08-21 11:01:52 UTC
</div>
</div>
</body>
diff --git a/docs/snapshot/grails-data/whats-new-manual/index.html
b/docs/snapshot/grails-data/whats-new-manual/index.html
index 89776839cad..6e132f65d92 100644
--- a/docs/snapshot/grails-data/whats-new-manual/index.html
+++ b/docs/snapshot/grails-data/whats-new-manual/index.html
@@ -527,7 +527,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 8.0.0-SNAPSHOT<br>
-Last updated 2026-08-20 23:44:26 UTC
+Last updated 2026-08-21 11:01:52 UTC
</div>
</div>
</body>
diff --git a/docs/snapshot/guide/security.html
b/docs/snapshot/guide/security.html
index 218a2751c2a..91d471f675e 100644
--- a/docs/snapshot/guide/security.html
+++ b/docs/snapshot/guide/security.html
@@ -1125,7 +1125,7 @@ Repeat last search
<p>The Spring Security plugins are built on the <a
href="https://spring.io/projects/spring-security">Spring Security</a> project
which provides a flexible, extensible framework for building all sorts of
authentication and authorization schemes. The plugins are modular so you can
install just the functionality that you need for your application. The Spring
Security plugins are the official security plugins for Grails and are actively
maintained and supported.</p>
</div>
<div class="paragraph">
-<p>The <strong>Core</strong> plugin supports form-based authentication,
encrypted/salted passwords, HTTP Basic authentication, etc. and secondary
dependent plugins provide alternate functionality such as ACL support, single
sign-on with Jasig CAS, LDAP authentication, OAuth2 client support, REST token
authentication, and a plugin providing user interface extensions and security
workflows.</p>
+<p>The <strong>Core</strong> plugin supports form-based authentication,
encrypted/salted passwords, HTTP Basic authentication, etc. and secondary
dependent plugins provide alternate functionality such as ACL support, single
sign-on with Apereo CAS, LDAP authentication, OAuth2 client support, REST token
authentication, and a plugin providing user interface extensions and security
workflows.</p>
</div>
<div class="paragraph">
<p>The reference documentation for each plugin is included in the following
sections:</p>
@@ -1139,7 +1139,7 @@ Repeat last search
<p><a href="#springSecurityAcl">ACL Plugin</a> — domain-instance-level
access control lists.</p>
</li>
<li>
-<p><a href="#springSecurityCas">CAS Plugin</a> — single sign-on with
Apereo (Jasig) CAS.</p>
+<p><a href="#springSecurityCas">CAS Plugin</a> — single sign-on with
Apereo CAS.</p>
</li>
<li>
<p><a href="#springSecurityLdap">LDAP Plugin</a> — authentication
against an LDAP server.</p>
@@ -9974,7 +9974,7 @@ the body content
<div class="sect2">
<h3 id="cas-introduction">Introduction to the Spring Security CAS Plugin</h3>
<div class="paragraph">
-<p>The CAS plugin adds <a href="https://www.jasig.org/cas">CAS</a> single
sign-on support to a Grails application that uses Spring Security. It depends
on the <a href="springSecurityCore.html#springSecurityCore">Spring Security
Core plugin</a>.</p>
+<p>The CAS plugin adds <a href="https://apereo.github.io/cas">CAS</a> single
sign-on support to a Grails application that uses Spring Security. It depends
on the <a href="springSecurityCore.html#springSecurityCore">Spring Security
Core plugin</a>.</p>
</div>
<div class="paragraph">
<p>Once you have configured a CAS server and have configured your Grails
application(s) as clients, you can authenticate to any application that is a
client of the CAS server and be automatically authenticated to all other
clients.</p>
@@ -9997,7 +9997,7 @@ the body content
</table>
</div>
<div class="paragraph">
-<p><a href="https://www.jasig.org/cas">CAS</a> is a popular single sign-on
implementation. It’s open source and has an Apache-like license, and is
easy to get started with but is also highly configurable. In addition it has
clients written in Java, .Net, PHP, Perl, and other languages.</p>
+<p><a href="https://apereo.github.io/cas">CAS</a> is a popular single sign-on
implementation. It’s open source and has an Apache-like license, and is
easy to get started with but is also highly configurable. In addition it has
clients written in Java, .Net, PHP, Perl, and other languages.</p>
</div>
<div class="sect3">
<h4 id="_installation">Installation</h4>
@@ -10034,7 +10034,22 @@ the body content
<div class="sect3">
<h4 id="_single_signout">Single Signout</h4>
<div class="paragraph">
-<p>Single signout is enabled by default and enables signing out for all
CAS-managed applications with one logout. This works best in the plugin when
combined with the <code>afterLogoutUrl</code> parameter, for example:</p>
+<p>Single signout enables signing out of all CAS-managed applications with one
logout. It is opt-in, because enabling it disables session fixation prevention
- CAS maps the service ticket to the HTTP session id, so a logout request
cannot be matched to a session that was replaced when the user
authenticated:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java">grails:
+ plugin:
+ springsecurity:
+ cas:
+ useSingleSignout: <span
class="predefined-constant">true</span></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The plugin prints and logs a warning at startup when it is enabled, so the
trade-off is visible.</p>
+</div>
+<div class="paragraph">
+<p>It works best when combined with the <code>afterLogoutUrl</code> parameter,
for example:</p>
</div>
<div class="listingblock">
<div class="content">
@@ -10049,7 +10064,8 @@ the body content
<p>With this configuration, when a user logs out locally by navigating to
<code>/logout/</code> they’ll then be redirected to the CAS
server’s logout URL. This request includes a local URL to redirect back
afterwards. When the whole process is finished they’ll be logged out
locally and at the CAS server, so subsequent secure URLs at the local server or
other CAS-managed servers will require a new login.</p>
</div>
<div class="paragraph">
-<p>If you don’t want the single signout filter registered, you can
disable the feature:</p>
+<p>To go back to the default and leave the single signout filter unregistered,
keeping session fixation
+prevention in place, set it to <code>false</code> or remove the setting:</p>
</div>
<div class="listingblock">
<div class="content">
@@ -10156,21 +10172,52 @@ the body content
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p
class="tableblock">cas.proxyCallbackUrl</p></td>
-<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>null</code>, should be set</p></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock">proxy
callback url, e.g. 'http://localhost:8080/secure/receptor'</p></td>
+<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>null</code></p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">proxy
callback url, e.g. 'http://localhost:8080/secure/receptor'. Only needed for
proxy tickets, and only meaningful together with
<code>cas.proxyReceptorUrl</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p
class="tableblock">cas.proxyReceptorUrl</p></td>
-<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>null</code>, should be set</p></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock">proxy
receptor url, e.g. '/secure/receptor'</p></td>
+<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>null</code></p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">proxy
receptor url, e.g. '/secure/receptor'. Only needed for proxy tickets, and only
meaningful together with <code>cas.proxyCallbackUrl</code>. When unset, no
request is treated as a proxy receptor request</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p
class="tableblock">cas.useSingleSignout</p></td>
-<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>true</code></p></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock">if
<code>true</code> a <code>org.jasig.cas.client.session.
SingleSignOutFilter</code> is registered</p></td>
+<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>false</code></p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">if
<code>true</code> a <code>org.apereo.cas.client.session.
SingleSignOutFilter</code> is registered, and session fixation prevention is
disabled (see below)</p></td>
</tr>
</tbody>
</table>
+<div class="admonitionblock warning">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-warning" title="Warning"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>Single sign-out and session fixation prevention cannot both be active. CAS
maps the service ticket
+to the HTTP session id, so if the session is replaced when the user
authenticates, the session CAS
+later asks the application to invalidate no longer exists and the logout
request has no effect.</p>
+</div>
+<div class="paragraph">
+<p><code>cas.useSingleSignout</code> is therefore opt-in. Enabling it makes
the plugin set
+<code>grails.plugin.springsecurity.useSessionFixationPrevention</code> to
<code>false</code> and define
+<code>sessionAuthenticationStrategy</code> accordingly, overriding whatever
the core plugin configured, and log
+a warning at startup so the trade-off is visible:</p>
+</div>
+<div class="listingblock">
+<div class="title">grails-app/conf/application.groovy</div>
+<div class="content">
+<pre class="CodeRay highlight"><code
data-lang="groovy">grails.plugin.springsecurity.cas.useSingleSignout = <span
class="predefined-constant">true</span></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Leave it off to keep session fixation prevention and handle logout in the
application instead.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
</div>
<div class="sect1">
<h2 id="_api_reference">API Reference</h2>
diff --git a/docs/snapshot/guide/single.html b/docs/snapshot/guide/single.html
index 24b5281e49c..c3c74d15710 100644
--- a/docs/snapshot/guide/single.html
+++ b/docs/snapshot/guide/single.html
@@ -6472,6 +6472,46 @@ once when it builds the message source.</p>
</div>
</div>
</div>
+<div class="sect3">
+<h4 id="_48_cas_single_sign_out_is_opt_in">48. CAS Single Sign-Out Is
Opt-In</h4>
+<div class="paragraph">
+<p><code>grails.plugin.springsecurity.cas.useSingleSignout</code> now defaults
to <code>false</code>. It previously defaulted
+to <code>true</code>, so every CAS application registered the CAS
client’s <code>SingleSignOutFilter</code> whether or not
+it wanted single sign-out.</p>
+</div>
+<div class="paragraph">
+<p>The default changed because enabling single sign-out is a security
trade-off rather than a free
+feature. CAS maps the service ticket to the HTTP session id, so single
sign-out cannot work while
+session fixation prevention is replacing the session when the user
authenticates. Enabling
+<code>cas.useSingleSignout</code> disables session fixation prevention, and an
application should make that
+choice deliberately.</p>
+</div>
+<div class="paragraph">
+<p>If your application relies on CAS single sign-out, enable it explicitly:</p>
+</div>
+<div class="listingblock">
+<div class="title">grails-app/conf/application.groovy</div>
+<div class="content">
+<pre class="CodeRay highlight"><code
data-lang="groovy">grails.plugin.springsecurity.cas.useSingleSignout = <span
class="predefined-constant">true</span></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The plugin logs a warning at startup when it is enabled, noting that
session fixation prevention has
+been disabled.</p>
+</div>
+<div class="paragraph">
+<p><strong>Single sign-out did not actually work before Grails 8</strong>, so
an application upgrading from an
+earlier version is unlikely to lose working behaviour. The plugin set
+<code>useSessionFixationPrevention = false</code> from
<code>doWithSpring</code>, but it declares <code>loadAfter =
+['springSecurityCore']</code>, so the core plugin had already defined
<code>sessionAuthenticationStrategy</code> from
+the original value. The filter was registered, the session was still replaced
on login, and CAS
+logout requests silently matched nothing. Grails 8 also redefines
<code>sessionAuthenticationStrategy</code>
+from the CAS plugin, so enabling <code>cas.useSingleSignout</code> now has the
documented effect.</p>
+</div>
+<div class="paragraph">
+<p>The Spring Security CAS configuration reference in this guide documents the
setting in full.</p>
+</div>
+</div>
</div>
@@ -39204,7 +39244,7 @@ Repeat last search
<p>The Spring Security plugins are built on the <a
href="https://spring.io/projects/spring-security">Spring Security</a> project
which provides a flexible, extensible framework for building all sorts of
authentication and authorization schemes. The plugins are modular so you can
install just the functionality that you need for your application. The Spring
Security plugins are the official security plugins for Grails and are actively
maintained and supported.</p>
</div>
<div class="paragraph">
-<p>The <strong>Core</strong> plugin supports form-based authentication,
encrypted/salted passwords, HTTP Basic authentication, etc. and secondary
dependent plugins provide alternate functionality such as ACL support, single
sign-on with Jasig CAS, LDAP authentication, OAuth2 client support, REST token
authentication, and a plugin providing user interface extensions and security
workflows.</p>
+<p>The <strong>Core</strong> plugin supports form-based authentication,
encrypted/salted passwords, HTTP Basic authentication, etc. and secondary
dependent plugins provide alternate functionality such as ACL support, single
sign-on with Apereo CAS, LDAP authentication, OAuth2 client support, REST token
authentication, and a plugin providing user interface extensions and security
workflows.</p>
</div>
<div class="paragraph">
<p>The reference documentation for each plugin is included in the following
sections:</p>
@@ -39218,7 +39258,7 @@ Repeat last search
<p><a href="#springSecurityAcl">ACL Plugin</a> — domain-instance-level
access control lists.</p>
</li>
<li>
-<p><a href="#springSecurityCas">CAS Plugin</a> — single sign-on with
Apereo (Jasig) CAS.</p>
+<p><a href="#springSecurityCas">CAS Plugin</a> — single sign-on with
Apereo CAS.</p>
</li>
<li>
<p><a href="#springSecurityLdap">LDAP Plugin</a> — authentication
against an LDAP server.</p>
@@ -48053,7 +48093,7 @@ the body content
<div class="sect2">
<h3 id="cas-introduction">Introduction to the Spring Security CAS Plugin</h3>
<div class="paragraph">
-<p>The CAS plugin adds <a href="https://www.jasig.org/cas">CAS</a> single
sign-on support to a Grails application that uses Spring Security. It depends
on the <a href="springSecurityCore.html#springSecurityCore">Spring Security
Core plugin</a>.</p>
+<p>The CAS plugin adds <a href="https://apereo.github.io/cas">CAS</a> single
sign-on support to a Grails application that uses Spring Security. It depends
on the <a href="springSecurityCore.html#springSecurityCore">Spring Security
Core plugin</a>.</p>
</div>
<div class="paragraph">
<p>Once you have configured a CAS server and have configured your Grails
application(s) as clients, you can authenticate to any application that is a
client of the CAS server and be automatically authenticated to all other
clients.</p>
@@ -48076,7 +48116,7 @@ the body content
</table>
</div>
<div class="paragraph">
-<p><a href="https://www.jasig.org/cas">CAS</a> is a popular single sign-on
implementation. It’s open source and has an Apache-like license, and is
easy to get started with but is also highly configurable. In addition it has
clients written in Java, .Net, PHP, Perl, and other languages.</p>
+<p><a href="https://apereo.github.io/cas">CAS</a> is a popular single sign-on
implementation. It’s open source and has an Apache-like license, and is
easy to get started with but is also highly configurable. In addition it has
clients written in Java, .Net, PHP, Perl, and other languages.</p>
</div>
<div class="sect3">
<h4 id="_installation">Installation</h4>
@@ -48113,7 +48153,22 @@ the body content
<div class="sect3">
<h4 id="_single_signout">Single Signout</h4>
<div class="paragraph">
-<p>Single signout is enabled by default and enables signing out for all
CAS-managed applications with one logout. This works best in the plugin when
combined with the <code>afterLogoutUrl</code> parameter, for example:</p>
+<p>Single signout enables signing out of all CAS-managed applications with one
logout. It is opt-in, because enabling it disables session fixation prevention
- CAS maps the service ticket to the HTTP session id, so a logout request
cannot be matched to a session that was replaced when the user
authenticated:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java">grails:
+ plugin:
+ springsecurity:
+ cas:
+ useSingleSignout: <span
class="predefined-constant">true</span></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The plugin prints and logs a warning at startup when it is enabled, so the
trade-off is visible.</p>
+</div>
+<div class="paragraph">
+<p>It works best when combined with the <code>afterLogoutUrl</code> parameter,
for example:</p>
</div>
<div class="listingblock">
<div class="content">
@@ -48128,7 +48183,8 @@ the body content
<p>With this configuration, when a user logs out locally by navigating to
<code>/logout/</code> they’ll then be redirected to the CAS
server’s logout URL. This request includes a local URL to redirect back
afterwards. When the whole process is finished they’ll be logged out
locally and at the CAS server, so subsequent secure URLs at the local server or
other CAS-managed servers will require a new login.</p>
</div>
<div class="paragraph">
-<p>If you don’t want the single signout filter registered, you can
disable the feature:</p>
+<p>To go back to the default and leave the single signout filter unregistered,
keeping session fixation
+prevention in place, set it to <code>false</code> or remove the setting:</p>
</div>
<div class="listingblock">
<div class="content">
@@ -48235,21 +48291,52 @@ the body content
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p
class="tableblock">cas.proxyCallbackUrl</p></td>
-<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>null</code>, should be set</p></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock">proxy
callback url, e.g. 'http://localhost:8080/secure/receptor'</p></td>
+<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>null</code></p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">proxy
callback url, e.g. 'http://localhost:8080/secure/receptor'. Only needed for
proxy tickets, and only meaningful together with
<code>cas.proxyReceptorUrl</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p
class="tableblock">cas.proxyReceptorUrl</p></td>
-<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>null</code>, should be set</p></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock">proxy
receptor url, e.g. '/secure/receptor'</p></td>
+<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>null</code></p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">proxy
receptor url, e.g. '/secure/receptor'. Only needed for proxy tickets, and only
meaningful together with <code>cas.proxyCallbackUrl</code>. When unset, no
request is treated as a proxy receptor request</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p
class="tableblock">cas.useSingleSignout</p></td>
-<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>true</code></p></td>
-<td class="tableblock halign-left valign-top"><p class="tableblock">if
<code>true</code> a <code>org.jasig.cas.client.session.
SingleSignOutFilter</code> is registered</p></td>
+<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>false</code></p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">if
<code>true</code> a <code>org.apereo.cas.client.session.
SingleSignOutFilter</code> is registered, and session fixation prevention is
disabled (see below)</p></td>
</tr>
</tbody>
</table>
+<div class="admonitionblock warning">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-warning" title="Warning"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>Single sign-out and session fixation prevention cannot both be active. CAS
maps the service ticket
+to the HTTP session id, so if the session is replaced when the user
authenticates, the session CAS
+later asks the application to invalidate no longer exists and the logout
request has no effect.</p>
+</div>
+<div class="paragraph">
+<p><code>cas.useSingleSignout</code> is therefore opt-in. Enabling it makes
the plugin set
+<code>grails.plugin.springsecurity.useSessionFixationPrevention</code> to
<code>false</code> and define
+<code>sessionAuthenticationStrategy</code> accordingly, overriding whatever
the core plugin configured, and log
+a warning at startup so the trade-off is visible:</p>
+</div>
+<div class="listingblock">
+<div class="title">grails-app/conf/application.groovy</div>
+<div class="content">
+<pre class="CodeRay highlight"><code
data-lang="groovy">grails.plugin.springsecurity.cas.useSingleSignout = <span
class="predefined-constant">true</span></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Leave it off to keep session fixation prevention and handle logout in the
application instead.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
</div>
<div class="sect1">
<h2 id="_api_reference">API Reference</h2>
diff --git a/docs/snapshot/guide/upgrading.html
b/docs/snapshot/guide/upgrading.html
index 5f62ee14cf9..7e8dd7f5fbf 100644
--- a/docs/snapshot/guide/upgrading.html
+++ b/docs/snapshot/guide/upgrading.html
@@ -3959,6 +3959,46 @@ once when it builds the message source.</p>
</div>
</div>
</div>
+<div class="sect3">
+<h4 id="_48_cas_single_sign_out_is_opt_in">48. CAS Single Sign-Out Is
Opt-In</h4>
+<div class="paragraph">
+<p><code>grails.plugin.springsecurity.cas.useSingleSignout</code> now defaults
to <code>false</code>. It previously defaulted
+to <code>true</code>, so every CAS application registered the CAS
client’s <code>SingleSignOutFilter</code> whether or not
+it wanted single sign-out.</p>
+</div>
+<div class="paragraph">
+<p>The default changed because enabling single sign-out is a security
trade-off rather than a free
+feature. CAS maps the service ticket to the HTTP session id, so single
sign-out cannot work while
+session fixation prevention is replacing the session when the user
authenticates. Enabling
+<code>cas.useSingleSignout</code> disables session fixation prevention, and an
application should make that
+choice deliberately.</p>
+</div>
+<div class="paragraph">
+<p>If your application relies on CAS single sign-out, enable it explicitly:</p>
+</div>
+<div class="listingblock">
+<div class="title">grails-app/conf/application.groovy</div>
+<div class="content">
+<pre class="CodeRay highlight"><code
data-lang="groovy">grails.plugin.springsecurity.cas.useSingleSignout = <span
class="predefined-constant">true</span></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The plugin logs a warning at startup when it is enabled, noting that
session fixation prevention has
+been disabled.</p>
+</div>
+<div class="paragraph">
+<p><strong>Single sign-out did not actually work before Grails 8</strong>, so
an application upgrading from an
+earlier version is unlikely to lose working behaviour. The plugin set
+<code>useSessionFixationPrevention = false</code> from
<code>doWithSpring</code>, but it declares <code>loadAfter =
+['springSecurityCore']</code>, so the core plugin had already defined
<code>sessionAuthenticationStrategy</code> from
+the original value. The filter was registered, the session was still replaced
on login, and CAS
+logout requests silently matched nothing. Grails 8 also redefines
<code>sessionAuthenticationStrategy</code>
+from the CAS plugin, so enabling <code>cas.useSingleSignout</code> now has the
documented effect.</p>
+</div>
+<div class="paragraph">
+<p>The Spring Security CAS configuration reference in this guide documents the
setting in full.</p>
+</div>
+</div>
</div>