You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by ja...@apache.org on 2026/02/26 18:20:06 UTC

(grails-spring-security) branch docs/spring-configuration-metadata created (now f1d6bed5d)

This is an automated email from the ASF dual-hosted git repository.

jamesfredley pushed a change to branch docs/spring-configuration-metadata
in repository https://gitbox.apache.org/repos/asf/grails-spring-security.git


      at f1d6bed5d docs: add configuration metadata reference

This branch includes the following new commits:

     new f1d6bed5d docs: add configuration metadata reference

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(grails-spring-security) 01/01: docs: add configuration metadata reference

Posted by ja...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jamesfredley pushed a commit to branch docs/spring-configuration-metadata
in repository https://gitbox.apache.org/repos/asf/grails-spring-security.git

commit f1d6bed5d908600e5a31a29b7bee3eaf2d9977b1
Author: James Fredley <ja...@users.noreply.github.com>
AuthorDate: Thu Feb 26 13:19:52 2026 -0500

    docs: add configuration metadata reference
    
    Add Spring configuration metadata for plugin properties and generate a configuration reference page in the docs build to surface these settings alongside the existing property tables.
    
    Assisted-by: OpenCode <op...@opencode.ai>
    
    Assisted-by: Claude Code <Cl...@Claude.ai>
---
 plugin-core/docs/build.gradle                      |  75 ++-
 .../docs/src/docs/configurationProperties.adoc     | 407 +++++++++++++
 plugin-core/docs/src/docs/index.adoc               |   2 +
 .../META-INF/spring-configuration-metadata.json    | 634 +++++++++++++++++++++
 4 files changed, 1117 insertions(+), 1 deletion(-)

diff --git a/plugin-core/docs/build.gradle b/plugin-core/docs/build.gradle
index a2af3fef4..ba5f45700 100644
--- a/plugin-core/docs/build.gradle
+++ b/plugin-core/docs/build.gradle
@@ -21,6 +21,8 @@ plugins {
     id 'groovy' // For groovydoc task
 }
 
+import groovy.json.JsonSlurper
+
 ext {
     apiDocsProjects = [
             'core-plugin': [
@@ -60,4 +62,75 @@ apply {
 dependencies {
     implementation platform("org.apache.grails:grails-bom:${grailsVersion}")
     implementation 'org.apache.groovy:groovy'
-}
\ No newline at end of file
+}
+
+def configurationMetadataFile = rootProject.layout.projectDirectory.file(
+        'plugin-core/plugin/src/main/resources/META-INF/spring-configuration-metadata.json'
+)
+def configurationPropertiesFile = layout.projectDirectory.file('src/docs/configurationProperties.adoc')
+
+tasks.register('generateConfigurationProperties') {
+    inputs.file(configurationMetadataFile)
+    outputs.file(configurationPropertiesFile)
+    doLast {
+        def metadata = new JsonSlurper().parse(configurationMetadataFile.asFile)
+        def groupsByName = (metadata.groups ?: []).collectEntries { group ->
+            [(group.name): group]
+        }
+        def propertiesByGroup = (metadata.properties ?: []).groupBy { property ->
+            property.group ?: 'grails.plugin.springsecurity.miscellaneous'
+        }
+        def orderedGroupNames = [
+                'grails.plugin.springsecurity.general',
+                'grails.plugin.springsecurity.domain-classes',
+                'grails.plugin.springsecurity.authentication',
+                'grails.plugin.springsecurity.login-logout',
+                'grails.plugin.springsecurity.password-encoding',
+                'grails.plugin.springsecurity.session',
+                'grails.plugin.springsecurity.url-mapping',
+                'grails.plugin.springsecurity.miscellaneous'
+        ]
+
+        configurationPropertiesFile.asFile.text = ''
+        configurationPropertiesFile.asFile << """= Configuration Properties
+
+This page is generated from `spring-configuration-metadata.json`. For IDE auto-completion of these properties, ensure the plugin JAR is on your classpath.
+"""
+
+        orderedGroupNames.each { groupName ->
+            def group = groupsByName[groupName]
+            def properties = propertiesByGroup[groupName] ?: []
+            if (!properties) {
+                return
+            }
+
+            def heading = group?.description ?: groupName
+            configurationPropertiesFile.asFile << """
+
+== ${heading}
+
+[cols=\"3,5,2\", options=\"header\"]
+|===
+|Property |Description |Default
+"""
+
+            properties.sort { it.name }.each { property ->
+                def defaultValue = property.containsKey('defaultValue') ? property.defaultValue : ''
+                def defaultText = defaultValue == null ? 'null' : defaultValue.toString()
+                configurationPropertiesFile.asFile << """
+|`${property.name}`
+|${property.description}
+|${defaultText}
+"""
+            }
+
+            configurationPropertiesFile.asFile << """
+|===
+"""
+        }
+    }
+}
+
+tasks.named('asciidoctor') {
+    dependsOn tasks.named('generateConfigurationProperties')
+}
diff --git a/plugin-core/docs/src/docs/configurationProperties.adoc b/plugin-core/docs/src/docs/configurationProperties.adoc
new file mode 100644
index 000000000..bce3fee4e
--- /dev/null
+++ b/plugin-core/docs/src/docs/configurationProperties.adoc
@@ -0,0 +1,407 @@
+= Configuration Properties
+
+This page is generated from `spring-configuration-metadata.json`. For IDE auto-completion of these properties, ensure the plugin JAR is on your classpath.
+
+
+== General configuration properties.
+
+[cols="3,5,2", options="header"]
+|===
+|Property |Description |Default
+
+|`grails.plugin.springsecurity.active`
+|Whether the plugin is enabled.
+|true
+
+|`grails.plugin.springsecurity.excludeSpringSecurityAutoConfiguration`
+|Whether to automatically exclude Spring Boot security auto-configuration classes that conflict with the plugin.
+|true
+
+|`grails.plugin.springsecurity.printStatusMessages`
+|Whether to print status messages such as "Configuring Spring Security Core ...".
+|true
+
+|`grails.plugin.springsecurity.rejectIfNoRule`
+|Strict mode where a request mapping is required for all resources.
+|true
+
+|===
+
+
+== Domain class configuration properties.
+
+[cols="3,5,2", options="header"]
+|===
+|Property |Description |Default
+
+|`grails.plugin.springsecurity.authority.className`
+|Role class name.
+|_none_
+
+|`grails.plugin.springsecurity.authority.nameField`
+|Role class role name property.
+|authority
+
+|`grails.plugin.springsecurity.requestMap.className`
+|Requestmap class name.
+|_none_
+
+|`grails.plugin.springsecurity.requestMap.configAttributeField`
+|Requestmap class role and token property.
+|configAttribute
+
+|`grails.plugin.springsecurity.requestMap.urlField`
+|Requestmap class URL pattern property.
+|url
+
+|`grails.plugin.springsecurity.userLookup.accountExpiredPropertyName`
+|User class account expired property.
+|accountExpired
+
+|`grails.plugin.springsecurity.userLookup.accountLockedPropertyName`
+|User class account locked property.
+|accountLocked
+
+|`grails.plugin.springsecurity.userLookup.authoritiesPropertyName`
+|User class role collection property.
+|authorities
+
+|`grails.plugin.springsecurity.userLookup.authorityJoinClassName`
+|User and role many-to-many join class name.
+|_none_
+
+|`grails.plugin.springsecurity.userLookup.enabledPropertyName`
+|User class enabled property.
+|enabled
+
+|`grails.plugin.springsecurity.userLookup.passwordExpiredPropertyName`
+|User class password expired property.
+|passwordExpired
+
+|`grails.plugin.springsecurity.userLookup.passwordPropertyName`
+|User class password property.
+|password
+
+|`grails.plugin.springsecurity.userLookup.userDomainClassName`
+|User class name.
+|_none_
+
+|`grails.plugin.springsecurity.userLookup.usernameIgnoreCase`
+|Ignore case when searching for usernamePropertyName.
+|false
+
+|`grails.plugin.springsecurity.userLookup.usernamePropertyName`
+|User class username property.
+|username
+
+|===
+
+
+== Authentication and authorization configuration properties.
+
+[cols="3,5,2", options="header"]
+|===
+|Property |Description |Default
+
+|`grails.plugin.springsecurity.anon.key`
+|anonymousProcessingFilter key.
+|foo
+
+|`grails.plugin.springsecurity.apf.continueChainBeforeSuccessfulAuthentication`
+|Whether to continue calling subsequent filters in the filter chain.
+|false
+
+|`grails.plugin.springsecurity.atr.anonymousClass`
+|Anonymous token class.
+|grails.plugin.springsecurity.authentication.GrailsAnonymousAuthenticationToken
+
+|`grails.plugin.springsecurity.dao.hideUserNotFoundExceptions`
+|If true, throws BadCredentialsException for both bad username and bad password.
+|true
+
+|`grails.plugin.springsecurity.fii.alwaysReauthenticate`
+|If true, re-authenticates when there is a Authentication in the SecurityContext.
+|false
+
+|`grails.plugin.springsecurity.fii.observeOncePerRequest`
+|If false allow checks to happen multiple times.
+|true
+
+|`grails.plugin.springsecurity.fii.publishAuthorizationSuccess`
+|Whether to publish an AuthorizedEvent after successful access check.
+|false
+
+|`grails.plugin.springsecurity.fii.rejectPublicInvocations`
+|Disallow URL access when there is no request mapping.
+|true
+
+|`grails.plugin.springsecurity.fii.validateConfigAttributes`
+|Whether to check that all ConfigAttribute instances are valid at startup.
+|true
+
+|`grails.plugin.springsecurity.providerManager.eraseCredentialsAfterAuthentication`
+|Whether to remove the password from the Authentication and its child objects after successful authentication.
+|true
+
+|`grails.plugin.springsecurity.providerNames`
+|Bean names of authentication providers.
+|[daoAuthenticationProvider, anonymousAuthenticationProvider, rememberMeAuthenticationProvider]
+
+|`grails.plugin.springsecurity.roleHierarchy`
+|Hierarchical role definition.
+|_none_
+
+|`grails.plugin.springsecurity.voterNames`
+|Bean names of voters.
+|[authenticatedVoter, roleVoter, closureVoter]
+
+|===
+
+
+== Login and logout configuration properties.
+
+[cols="3,5,2", options="header"]
+|===
+|Property |Description |Default
+
+|`grails.plugin.springsecurity.adh.ajaxErrorPage`
+|Location of the 403 error page for Ajax requests.
+|/login/ajaxDenied
+
+|`grails.plugin.springsecurity.adh.errorPage`
+|Location of the 403 error page (or set to null to send a 403 error and not render a page).
+|/login/denied
+
+|`grails.plugin.springsecurity.adh.useForward`
+|If true a forward will be used to render the error page, otherwise a redirect is used.
+|true
+
+|`grails.plugin.springsecurity.apf.filterProcessesUrl`
+|Login form post URL, intercepted by Spring Security filter.
+|/login/authenticate
+
+|`grails.plugin.springsecurity.apf.passwordParameter`
+|Login form password parameter.
+|password
+
+|`grails.plugin.springsecurity.apf.postOnly`
+|Whether to allow only POST login requests.
+|true
+
+|`grails.plugin.springsecurity.apf.usernameParameter`
+|Login form username parameter.
+|username
+
+|`grails.plugin.springsecurity.auth.ajaxLoginFormUrl`
+|URL of Ajax login page.
+|/login/authAjax
+
+|`grails.plugin.springsecurity.auth.forceHttps`
+|If true, redirects login page requests to HTTPS.
+|false
+
+|`grails.plugin.springsecurity.auth.loginFormUrl`
+|URL of login page.
+|/login/auth
+
+|`grails.plugin.springsecurity.auth.useForward`
+|Whether to render the login page (true) or redirect (false).
+|false
+
+|`grails.plugin.springsecurity.failureHandler.ajaxAuthFailUrl`
+|Redirect URL for failed Ajax logins.
+|/login/authfail?ajax=true
+
+|`grails.plugin.springsecurity.failureHandler.defaultFailureUrl`
+|Redirect URL for failed logins.
+|/login/authfail?login_error=1
+
+|`grails.plugin.springsecurity.failureHandler.exceptionMappings`
+|Map of AuthenticationException subclasses to redirect URLs after authentication failure.
+|_none_
+
+|`grails.plugin.springsecurity.failureHandler.useForward`
+|Whether to render the error page (true) or redirect (false).
+|false
+
+|`grails.plugin.springsecurity.logout.afterLogoutUrl`
+|URL for redirect after logout.
+|/
+
+|`grails.plugin.springsecurity.logout.alwaysUseDefaultTargetUrl`
+|Whether to always use afterLogoutUrl as the post-logout URL.
+|false
+
+|`grails.plugin.springsecurity.logout.clearAuthentication`
+|If true removes the Authentication from the SecurityContext to prevent issues with concurrent requests.
+|true
+
+|`grails.plugin.springsecurity.logout.filterProcessesUrl`
+|Logout URL, intercepted by Spring Security filter.
+|/logoff
+
+|`grails.plugin.springsecurity.logout.handlerNames`
+|Logout handler bean names.
+|[rememberMeServices, securityContextLogoutHandler]
+
+|`grails.plugin.springsecurity.logout.postOnly`
+|If true only POST requests will be allowed to logout.
+|true
+
+|`grails.plugin.springsecurity.logout.redirectToReferer`
+|Whether to use the Referer header value as the post-logout URL.
+|false
+
+|`grails.plugin.springsecurity.logout.targetUrlParameter`
+|The querystring parameter name for the post-logout URL.
+|_none_
+
+|`grails.plugin.springsecurity.successHandler.ajaxSuccessUrl`
+|URL for redirect after successful Ajax login.
+|/login/ajaxSuccess
+
+|`grails.plugin.springsecurity.successHandler.alwaysUseDefault`
+|Whether to always redirect to successHandler.defaultTargetUrl after successful authentication.
+|false
+
+|`grails.plugin.springsecurity.successHandler.defaultTargetUrl`
+|Default post-login URL if there is no saved request that triggered the login.
+|/
+
+|`grails.plugin.springsecurity.successHandler.targetUrlParameter`
+|Name of optional login form parameter that specifies destination after successful login.
+|spring-security-redirect
+
+|`grails.plugin.springsecurity.successHandler.useReferer`
+|Whether to use the HTTP Referer header to determine post-login destination.
+|false
+
+|===
+
+
+== Password encoding configuration properties.
+
+[cols="3,5,2", options="header"]
+|===
+|Property |Description |Default
+
+|`grails.plugin.springsecurity.dao.reflectionSaltSourceProperty`
+|Which property to use for the reflection-based salt source.
+|_none_
+
+|===
+
+
+== Session and security context configuration properties.
+
+[cols="3,5,2", options="header"]
+|===
+|Property |Description |Default
+
+|`grails.plugin.springsecurity.apf.allowSessionCreation`
+|Whether to allow authentication to create an HTTP session.
+|true
+
+|`grails.plugin.springsecurity.apf.storeLastUsername`
+|Whether to store the login username in the HTTP session.
+|false
+
+|`grails.plugin.springsecurity.failureHandler.allowSessionCreation`
+|Whether to enable session creation to store the authentication failure exception.
+|true
+
+|`grails.plugin.springsecurity.logout.invalidateHttpSession`
+|Whether to invalidate the HTTP session when logging out.
+|true
+
+|`grails.plugin.springsecurity.requestCache.createSession`
+|Whether caching SavedRequest can trigger the creation of a session.
+|true
+
+|`grails.plugin.springsecurity.sch.strategyName`
+|The strategy to use for storing the SecurityContext.
+|SecurityContextHolder.MODE_THREADLOCAL
+
+|`grails.plugin.springsecurity.scpf.forceEagerSessionCreation`
+|Whether to eagerly create a session in the securityContextRepository bean.
+|false
+
+|`grails.plugin.springsecurity.scr.allowSessionCreation`
+|Whether to allow creating a session in the securityContextRepository bean.
+|true
+
+|`grails.plugin.springsecurity.scr.disableUrlRewriting`
+|Whether to disable URL rewriting (and the jsessionid attribute).
+|true
+
+|`grails.plugin.springsecurity.scr.springSecurityContextKey`
+|The HTTP session key to store the SecurityContext under.
+|HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY
+
+|`grails.plugin.springsecurity.useHttpSessionEventPublisher`
+|If true, an HttpSessionEventPublisher will be configured.
+|false
+
+|===
+
+
+== URL mapping configuration properties.
+
+[cols="3,5,2", options="header"]
+|===
+|Property |Description |Default
+
+|`grails.plugin.springsecurity.controllerAnnotations.lowercase`
+|Whether to do URL comparisons using lowercase.
+|true
+
+|`grails.plugin.springsecurity.controllerAnnotations.staticRules`
+|Extra rules that cannot be mapped using annotations.
+|_none_
+
+|`grails.plugin.springsecurity.interceptUrlMap`
+|Request mapping definition when using InterceptUrlMap.
+|_none_
+
+|`grails.plugin.springsecurity.redirectStrategy.contextRelative`
+|If true, the redirect URL will be the value after the request context path.
+|false
+
+|`grails.plugin.springsecurity.securityConfigType`
+|Type of request mapping to use, one of Annotation, Requestmap, or InterceptUrlMap.
+|Annotation
+
+|===
+
+
+== Miscellaneous configuration properties.
+
+[cols="3,5,2", options="header"]
+|===
+|Property |Description |Default
+
+|`grails.plugin.springsecurity.ajaxCheckClosure`
+|An optional closure that can determine if a request is Ajax.
+|_none_
+
+|`grails.plugin.springsecurity.ajaxHeader`
+|Header name sent by Ajax library, used to detect Ajax.
+|X-Requested-With
+
+|`grails.plugin.springsecurity.cacheUsers`
+|If true, logins are cached using an EhCache.
+|false
+
+|`grails.plugin.springsecurity.debug.useFilter`
+|Whether to use the DebugFilter to log request debug information to the console.
+|false
+
+|`grails.plugin.springsecurity.registerLoggerListener`
+|If true, registers a LoggerListener that logs interceptor-related application events.
+|false
+
+|`grails.plugin.springsecurity.useSecurityEventListener`
+|If true, configure SecurityEventListener.
+|false
+
+|===
diff --git a/plugin-core/docs/src/docs/index.adoc b/plugin-core/docs/src/docs/index.adoc
index 2643cf65b..9fb76225c 100644
--- a/plugin-core/docs/src/docs/index.adoc
+++ b/plugin-core/docs/src/docs/index.adoc
@@ -67,6 +67,8 @@ include::voters.adoc[]
 
 include::miscProperties.adoc[]
 
+include::configurationProperties.adoc[]
+
 include::tutorials.adoc[]
 
 include::examples.adoc[]
diff --git a/plugin-core/plugin/src/main/resources/META-INF/spring-configuration-metadata.json b/plugin-core/plugin/src/main/resources/META-INF/spring-configuration-metadata.json
new file mode 100644
index 000000000..a4f678887
--- /dev/null
+++ b/plugin-core/plugin/src/main/resources/META-INF/spring-configuration-metadata.json
@@ -0,0 +1,634 @@
+{
+  "groups": [
+    {
+      "name": "grails.plugin.springsecurity",
+      "description": "Apache License 2.0 applies to this metadata. JSON files cannot include comment headers."
+    },
+    {
+      "name": "grails.plugin.springsecurity.general",
+      "description": "General configuration properties."
+    },
+    {
+      "name": "grails.plugin.springsecurity.domain-classes",
+      "description": "Domain class configuration properties."
+    },
+    {
+      "name": "grails.plugin.springsecurity.authentication",
+      "description": "Authentication and authorization configuration properties."
+    },
+    {
+      "name": "grails.plugin.springsecurity.login-logout",
+      "description": "Login and logout configuration properties."
+    },
+    {
+      "name": "grails.plugin.springsecurity.password-encoding",
+      "description": "Password encoding configuration properties."
+    },
+    {
+      "name": "grails.plugin.springsecurity.session",
+      "description": "Session and security context configuration properties."
+    },
+    {
+      "name": "grails.plugin.springsecurity.url-mapping",
+      "description": "URL mapping configuration properties."
+    },
+    {
+      "name": "grails.plugin.springsecurity.miscellaneous",
+      "description": "Miscellaneous configuration properties."
+    }
+  ],
+  "properties": [
+    {
+      "name": "grails.plugin.springsecurity.active",
+      "type": "java.lang.Boolean",
+      "description": "Whether the plugin is enabled.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.general"
+    },
+    {
+      "name": "grails.plugin.springsecurity.printStatusMessages",
+      "type": "java.lang.Boolean",
+      "description": "Whether to print status messages such as \"Configuring Spring Security Core ...\".",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.general"
+    },
+    {
+      "name": "grails.plugin.springsecurity.rejectIfNoRule",
+      "type": "java.lang.Boolean",
+      "description": "Strict mode where a request mapping is required for all resources.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.general"
+    },
+    {
+      "name": "grails.plugin.springsecurity.excludeSpringSecurityAutoConfiguration",
+      "type": "java.lang.Boolean",
+      "description": "Whether to automatically exclude Spring Boot security auto-configuration classes that conflict with the plugin.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.general"
+    },
+    {
+      "name": "grails.plugin.springsecurity.userLookup.userDomainClassName",
+      "type": "java.lang.String",
+      "description": "User class name.",
+      "defaultValue": "_none_",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.userLookup.usernamePropertyName",
+      "type": "java.lang.String",
+      "description": "User class username property.",
+      "defaultValue": "username",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.userLookup.usernameIgnoreCase",
+      "type": "java.lang.Boolean",
+      "description": "Ignore case when searching for usernamePropertyName.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.userLookup.passwordPropertyName",
+      "type": "java.lang.String",
+      "description": "User class password property.",
+      "defaultValue": "password",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.userLookup.authoritiesPropertyName",
+      "type": "java.lang.String",
+      "description": "User class role collection property.",
+      "defaultValue": "authorities",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.userLookup.enabledPropertyName",
+      "type": "java.lang.String",
+      "description": "User class enabled property.",
+      "defaultValue": "enabled",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.userLookup.accountExpiredPropertyName",
+      "type": "java.lang.String",
+      "description": "User class account expired property.",
+      "defaultValue": "accountExpired",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.userLookup.accountLockedPropertyName",
+      "type": "java.lang.String",
+      "description": "User class account locked property.",
+      "defaultValue": "accountLocked",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.userLookup.passwordExpiredPropertyName",
+      "type": "java.lang.String",
+      "description": "User class password expired property.",
+      "defaultValue": "passwordExpired",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.userLookup.authorityJoinClassName",
+      "type": "java.lang.String",
+      "description": "User and role many-to-many join class name.",
+      "defaultValue": "_none_",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.authority.className",
+      "type": "java.lang.String",
+      "description": "Role class name.",
+      "defaultValue": "_none_",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.authority.nameField",
+      "type": "java.lang.String",
+      "description": "Role class role name property.",
+      "defaultValue": "authority",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.requestMap.className",
+      "type": "java.lang.String",
+      "description": "Requestmap class name.",
+      "defaultValue": "_none_",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.requestMap.urlField",
+      "type": "java.lang.String",
+      "description": "Requestmap class URL pattern property.",
+      "defaultValue": "url",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.requestMap.configAttributeField",
+      "type": "java.lang.String",
+      "description": "Requestmap class role and token property.",
+      "defaultValue": "configAttribute",
+      "group": "grails.plugin.springsecurity.domain-classes"
+    },
+    {
+      "name": "grails.plugin.springsecurity.apf.filterProcessesUrl",
+      "type": "java.lang.String",
+      "description": "Login form post URL, intercepted by Spring Security filter.",
+      "defaultValue": "/login/authenticate",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.apf.usernameParameter",
+      "type": "java.lang.String",
+      "description": "Login form username parameter.",
+      "defaultValue": "username",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.apf.passwordParameter",
+      "type": "java.lang.String",
+      "description": "Login form password parameter.",
+      "defaultValue": "password",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.apf.allowSessionCreation",
+      "type": "java.lang.Boolean",
+      "description": "Whether to allow authentication to create an HTTP session.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.session"
+    },
+    {
+      "name": "grails.plugin.springsecurity.apf.postOnly",
+      "type": "java.lang.Boolean",
+      "description": "Whether to allow only POST login requests.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.apf.continueChainBeforeSuccessfulAuthentication",
+      "type": "java.lang.Boolean",
+      "description": "Whether to continue calling subsequent filters in the filter chain.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.authentication"
+    },
+    {
+      "name": "grails.plugin.springsecurity.apf.storeLastUsername",
+      "type": "java.lang.Boolean",
+      "description": "Whether to store the login username in the HTTP session.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.session"
+    },
+    {
+      "name": "grails.plugin.springsecurity.failureHandler.defaultFailureUrl",
+      "type": "java.lang.String",
+      "description": "Redirect URL for failed logins.",
+      "defaultValue": "/login/authfail?login_error=1",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.failureHandler.ajaxAuthFailUrl",
+      "type": "java.lang.String",
+      "description": "Redirect URL for failed Ajax logins.",
+      "defaultValue": "/login/authfail?ajax=true",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.failureHandler.exceptionMappings",
+      "type": "java.util.Map",
+      "description": "Map of AuthenticationException subclasses to redirect URLs after authentication failure.",
+      "defaultValue": "_none_",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.failureHandler.useForward",
+      "type": "java.lang.Boolean",
+      "description": "Whether to render the error page (true) or redirect (false).",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.failureHandler.allowSessionCreation",
+      "type": "java.lang.Boolean",
+      "description": "Whether to enable session creation to store the authentication failure exception.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.session"
+    },
+    {
+      "name": "grails.plugin.springsecurity.successHandler.defaultTargetUrl",
+      "type": "java.lang.String",
+      "description": "Default post-login URL if there is no saved request that triggered the login.",
+      "defaultValue": "/",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.successHandler.alwaysUseDefault",
+      "type": "java.lang.Boolean",
+      "description": "Whether to always redirect to successHandler.defaultTargetUrl after successful authentication.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.successHandler.targetUrlParameter",
+      "type": "java.lang.String",
+      "description": "Name of optional login form parameter that specifies destination after successful login.",
+      "defaultValue": "spring-security-redirect",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.successHandler.useReferer",
+      "type": "java.lang.Boolean",
+      "description": "Whether to use the HTTP Referer header to determine post-login destination.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.successHandler.ajaxSuccessUrl",
+      "type": "java.lang.String",
+      "description": "URL for redirect after successful Ajax login.",
+      "defaultValue": "/login/ajaxSuccess",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.auth.loginFormUrl",
+      "type": "java.lang.String",
+      "description": "URL of login page.",
+      "defaultValue": "/login/auth",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.auth.forceHttps",
+      "type": "java.lang.Boolean",
+      "description": "If true, redirects login page requests to HTTPS.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.auth.ajaxLoginFormUrl",
+      "type": "java.lang.String",
+      "description": "URL of Ajax login page.",
+      "defaultValue": "/login/authAjax",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.auth.useForward",
+      "type": "java.lang.Boolean",
+      "description": "Whether to render the login page (true) or redirect (false).",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.logout.afterLogoutUrl",
+      "type": "java.lang.String",
+      "description": "URL for redirect after logout.",
+      "defaultValue": "/",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.logout.filterProcessesUrl",
+      "type": "java.lang.String",
+      "description": "Logout URL, intercepted by Spring Security filter.",
+      "defaultValue": "/logoff",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.logout.handlerNames",
+      "type": "java.util.List",
+      "description": "Logout handler bean names.",
+      "defaultValue": [
+        "rememberMeServices",
+        "securityContextLogoutHandler"
+      ],
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.logout.clearAuthentication",
+      "type": "java.lang.Boolean",
+      "description": "If true removes the Authentication from the SecurityContext to prevent issues with concurrent requests.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.logout.invalidateHttpSession",
+      "type": "java.lang.Boolean",
+      "description": "Whether to invalidate the HTTP session when logging out.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.session"
+    },
+    {
+      "name": "grails.plugin.springsecurity.logout.targetUrlParameter",
+      "type": "java.lang.String",
+      "description": "The querystring parameter name for the post-logout URL.",
+      "defaultValue": "_none_",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.logout.alwaysUseDefaultTargetUrl",
+      "type": "java.lang.Boolean",
+      "description": "Whether to always use afterLogoutUrl as the post-logout URL.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.logout.redirectToReferer",
+      "type": "java.lang.Boolean",
+      "description": "Whether to use the Referer header value as the post-logout URL.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.logout.postOnly",
+      "type": "java.lang.Boolean",
+      "description": "If true only POST requests will be allowed to logout.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.adh.errorPage",
+      "type": "java.lang.String",
+      "description": "Location of the 403 error page (or set to null to send a 403 error and not render a page).",
+      "defaultValue": "/login/denied",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.adh.ajaxErrorPage",
+      "type": "java.lang.String",
+      "description": "Location of the 403 error page for Ajax requests.",
+      "defaultValue": "/login/ajaxDenied",
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.adh.useForward",
+      "type": "java.lang.Boolean",
+      "description": "If true a forward will be used to render the error page, otherwise a redirect is used.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.login-logout"
+    },
+    {
+      "name": "grails.plugin.springsecurity.ajaxHeader",
+      "type": "java.lang.String",
+      "description": "Header name sent by Ajax library, used to detect Ajax.",
+      "defaultValue": "X-Requested-With",
+      "group": "grails.plugin.springsecurity.miscellaneous"
+    },
+    {
+      "name": "grails.plugin.springsecurity.ajaxCheckClosure",
+      "type": "groovy.lang.Closure",
+      "description": "An optional closure that can determine if a request is Ajax.",
+      "defaultValue": "_none_",
+      "group": "grails.plugin.springsecurity.miscellaneous"
+    },
+    {
+      "name": "grails.plugin.springsecurity.redirectStrategy.contextRelative",
+      "type": "java.lang.Boolean",
+      "description": "If true, the redirect URL will be the value after the request context path.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.url-mapping"
+    },
+    {
+      "name": "grails.plugin.springsecurity.fii.alwaysReauthenticate",
+      "type": "java.lang.Boolean",
+      "description": "If true, re-authenticates when there is a Authentication in the SecurityContext.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.authentication"
+    },
+    {
+      "name": "grails.plugin.springsecurity.fii.rejectPublicInvocations",
+      "type": "java.lang.Boolean",
+      "description": "Disallow URL access when there is no request mapping.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.authentication"
+    },
+    {
+      "name": "grails.plugin.springsecurity.fii.validateConfigAttributes",
+      "type": "java.lang.Boolean",
+      "description": "Whether to check that all ConfigAttribute instances are valid at startup.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.authentication"
+    },
+    {
+      "name": "grails.plugin.springsecurity.fii.publishAuthorizationSuccess",
+      "type": "java.lang.Boolean",
+      "description": "Whether to publish an AuthorizedEvent after successful access check.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.authentication"
+    },
+    {
+      "name": "grails.plugin.springsecurity.fii.observeOncePerRequest",
+      "type": "java.lang.Boolean",
+      "description": "If false allow checks to happen multiple times.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.authentication"
+    },
+    {
+      "name": "grails.plugin.springsecurity.anon.key",
+      "type": "java.lang.String",
+      "description": "anonymousProcessingFilter key.",
+      "defaultValue": "foo",
+      "group": "grails.plugin.springsecurity.authentication"
+    },
+    {
+      "name": "grails.plugin.springsecurity.atr.anonymousClass",
+      "type": "java.lang.String",
+      "description": "Anonymous token class.",
+      "defaultValue": "grails.plugin.springsecurity.authentication.GrailsAnonymousAuthenticationToken",
+      "group": "grails.plugin.springsecurity.authentication"
+    },
+    {
+      "name": "grails.plugin.springsecurity.useHttpSessionEventPublisher",
+      "type": "java.lang.Boolean",
+      "description": "If true, an HttpSessionEventPublisher will be configured.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.session"
+    },
+    {
+      "name": "grails.plugin.springsecurity.cacheUsers",
+      "type": "java.lang.Boolean",
+      "description": "If true, logins are cached using an EhCache.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.miscellaneous"
+    },
+    {
+      "name": "grails.plugin.springsecurity.useSecurityEventListener",
+      "type": "java.lang.Boolean",
+      "description": "If true, configure SecurityEventListener.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.miscellaneous"
+    },
+    {
+      "name": "grails.plugin.springsecurity.dao.reflectionSaltSourceProperty",
+      "type": "java.lang.String",
+      "description": "Which property to use for the reflection-based salt source.",
+      "defaultValue": "_none_",
+      "group": "grails.plugin.springsecurity.password-encoding"
+    },
+    {
+      "name": "grails.plugin.springsecurity.dao.hideUserNotFoundExceptions",
+      "type": "java.lang.Boolean",
+      "description": "If true, throws BadCredentialsException for both bad username and bad password.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.authentication"
+    },
+    {
+      "name": "grails.plugin.springsecurity.requestCache.createSession",
+      "type": "java.lang.Boolean",
+      "description": "Whether caching SavedRequest can trigger the creation of a session.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.session"
+    },
+    {
+      "name": "grails.plugin.springsecurity.roleHierarchy",
+      "type": "java.lang.String",
+      "description": "Hierarchical role definition.",
+      "defaultValue": "_none_",
+      "group": "grails.plugin.springsecurity.authentication"
+    },
+    {
+      "name": "grails.plugin.springsecurity.voterNames",
+      "type": "java.util.List",
+      "description": "Bean names of voters.",
+      "defaultValue": [
+        "authenticatedVoter",
+        "roleVoter",
+        "closureVoter"
+      ],
+      "group": "grails.plugin.springsecurity.authentication"
+    },
+    {
+      "name": "grails.plugin.springsecurity.providerNames",
+      "type": "java.util.List",
+      "description": "Bean names of authentication providers.",
+      "defaultValue": [
+        "daoAuthenticationProvider",
+        "anonymousAuthenticationProvider",
+        "rememberMeAuthenticationProvider"
+      ],
+      "group": "grails.plugin.springsecurity.authentication"
+    },
+    {
+      "name": "grails.plugin.springsecurity.securityConfigType",
+      "type": "java.lang.String",
+      "description": "Type of request mapping to use, one of Annotation, Requestmap, or InterceptUrlMap.",
+      "defaultValue": "Annotation",
+      "group": "grails.plugin.springsecurity.url-mapping"
+    },
+    {
+      "name": "grails.plugin.springsecurity.controllerAnnotations.lowercase",
+      "type": "java.lang.Boolean",
+      "description": "Whether to do URL comparisons using lowercase.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.url-mapping"
+    },
+    {
+      "name": "grails.plugin.springsecurity.controllerAnnotations.staticRules",
+      "type": "java.util.List",
+      "description": "Extra rules that cannot be mapped using annotations.",
+      "defaultValue": "_none_",
+      "group": "grails.plugin.springsecurity.url-mapping"
+    },
+    {
+      "name": "grails.plugin.springsecurity.interceptUrlMap",
+      "type": "java.util.List",
+      "description": "Request mapping definition when using InterceptUrlMap.",
+      "defaultValue": "_none_",
+      "group": "grails.plugin.springsecurity.url-mapping"
+    },
+    {
+      "name": "grails.plugin.springsecurity.registerLoggerListener",
+      "type": "java.lang.Boolean",
+      "description": "If true, registers a LoggerListener that logs interceptor-related application events.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.miscellaneous"
+    },
+    {
+      "name": "grails.plugin.springsecurity.scr.allowSessionCreation",
+      "type": "java.lang.Boolean",
+      "description": "Whether to allow creating a session in the securityContextRepository bean.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.session"
+    },
+    {
+      "name": "grails.plugin.springsecurity.scr.disableUrlRewriting",
+      "type": "java.lang.Boolean",
+      "description": "Whether to disable URL rewriting (and the jsessionid attribute).",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.session"
+    },
+    {
+      "name": "grails.plugin.springsecurity.scr.springSecurityContextKey",
+      "type": "java.lang.String",
+      "description": "The HTTP session key to store the SecurityContext under.",
+      "defaultValue": "HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY",
+      "group": "grails.plugin.springsecurity.session"
+    },
+    {
+      "name": "grails.plugin.springsecurity.scpf.forceEagerSessionCreation",
+      "type": "java.lang.Boolean",
+      "description": "Whether to eagerly create a session in the securityContextRepository bean.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.session"
+    },
+    {
+      "name": "grails.plugin.springsecurity.sch.strategyName",
+      "type": "java.lang.String",
+      "description": "The strategy to use for storing the SecurityContext.",
+      "defaultValue": "SecurityContextHolder.MODE_THREADLOCAL",
+      "group": "grails.plugin.springsecurity.session"
+    },
+    {
+      "name": "grails.plugin.springsecurity.debug.useFilter",
+      "type": "java.lang.Boolean",
+      "description": "Whether to use the DebugFilter to log request debug information to the console.",
+      "defaultValue": false,
+      "group": "grails.plugin.springsecurity.miscellaneous"
+    },
+    {
+      "name": "grails.plugin.springsecurity.providerManager.eraseCredentialsAfterAuthentication",
+      "type": "java.lang.Boolean",
+      "description": "Whether to remove the password from the Authentication and its child objects after successful authentication.",
+      "defaultValue": true,
+      "group": "grails.plugin.springsecurity.authentication"
+    }
+  ]
+}