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

jamesfredley pushed a commit to branch fix/auto-exclude-security-autoconfig
in repository https://gitbox.apache.org/repos/asf/grails-spring-security.git

commit db38e2c99ac03c5825180c433cb556cd484198c1
Author: James Fredley <[email protected]>
AuthorDate: Thu Feb 19 09:41:28 2026 -0500

    feat: add opt-out property for auto-configuration exclusion filter
    
    Users can now disable the automatic exclusion of Spring Boot security
    auto-configurations by setting:
    
      grails.plugin.springsecurity.excludeSpringSecurityAutoConfiguration: false
    
    in application.yml. The filter implements EnvironmentAware so it reads
    the property during the auto-configuration discovery phase. Defaults to
    true (exclusions active) for backward compatibility.
    
    Assisted-by: Claude Code <[email protected]>
---
 .../SecurityAutoConfigurationExcluder.groovy       | 25 +++++++++-
 .../SecurityAutoConfigurationExcluderSpec.groovy   | 54 ++++++++++++++++++++++
 2 files changed, 77 insertions(+), 2 deletions(-)

diff --git 
a/plugin-core/plugin/src/main/groovy/grails/plugin/springsecurity/SecurityAutoConfigurationExcluder.groovy
 
b/plugin-core/plugin/src/main/groovy/grails/plugin/springsecurity/SecurityAutoConfigurationExcluder.groovy
index 798b86b31..21b2ce8c1 100644
--- 
a/plugin-core/plugin/src/main/groovy/grails/plugin/springsecurity/SecurityAutoConfigurationExcluder.groovy
+++ 
b/plugin-core/plugin/src/main/groovy/grails/plugin/springsecurity/SecurityAutoConfigurationExcluder.groovy
@@ -21,6 +21,8 @@ package grails.plugin.springsecurity
 import groovy.transform.CompileStatic
 import org.springframework.boot.autoconfigure.AutoConfigurationImportFilter
 import org.springframework.boot.autoconfigure.AutoConfigurationMetadata
+import org.springframework.context.EnvironmentAware
+import org.springframework.core.env.Environment
 
 /**
  * Automatically excludes Spring Boot security auto-configuration classes that
@@ -38,6 +40,16 @@ import 
org.springframework.boot.autoconfigure.AutoConfigurationMetadata
  * automatically filtering them out during Spring Boot's auto-configuration
  * discovery phase.</p>
  *
+ * <p>To disable this filter and allow Spring Boot's security 
auto-configurations
+ * to run, set the following property in {@code application.yml}:</p>
+ *
+ * <pre>
+ * grails:
+ *   plugin:
+ *     springsecurity:
+ *       excludeSpringSecurityAutoConfiguration: false
+ * </pre>
+ *
  * <p>Registered via {@code META-INF/spring.factories} as an
  * {@link AutoConfigurationImportFilter}. This runs before auto-configuration
  * bytecode is loaded, so there is no performance overhead from excluded 
classes.</p>
@@ -46,7 +58,16 @@ import 
org.springframework.boot.autoconfigure.AutoConfigurationMetadata
  * @see AutoConfigurationImportFilter
  */
 @CompileStatic
-class SecurityAutoConfigurationExcluder implements 
AutoConfigurationImportFilter {
+class SecurityAutoConfigurationExcluder implements 
AutoConfigurationImportFilter, EnvironmentAware {
+
+    static final String ENABLED_PROPERTY = 
'grails.plugin.springsecurity.excludeSpringSecurityAutoConfiguration'
+
+    private boolean enabled = true
+
+    @Override
+    void setEnvironment(Environment environment) {
+        this.enabled = environment.getProperty(ENABLED_PROPERTY, Boolean, true)
+    }
 
     /**
      * Spring Boot security auto-configuration classes that conflict with the
@@ -86,7 +107,7 @@ class SecurityAutoConfigurationExcluder implements 
AutoConfigurationImportFilter
     boolean[] match(String[] autoConfigurationClasses, 
AutoConfigurationMetadata autoConfigurationMetadata) {
         boolean[] matches = new boolean[autoConfigurationClasses.length]
         for (int i = 0; i < autoConfigurationClasses.length; i++) {
-            matches[i] = 
!EXCLUDED_AUTO_CONFIGURATIONS.contains(autoConfigurationClasses[i])
+            matches[i] = !enabled || 
!EXCLUDED_AUTO_CONFIGURATIONS.contains(autoConfigurationClasses[i])
         }
         return matches
     }
diff --git 
a/plugin-core/plugin/src/test/groovy/grails/plugin/springsecurity/SecurityAutoConfigurationExcluderSpec.groovy
 
b/plugin-core/plugin/src/test/groovy/grails/plugin/springsecurity/SecurityAutoConfigurationExcluderSpec.groovy
index 0a848d953..bab018283 100644
--- 
a/plugin-core/plugin/src/test/groovy/grails/plugin/springsecurity/SecurityAutoConfigurationExcluderSpec.groovy
+++ 
b/plugin-core/plugin/src/test/groovy/grails/plugin/springsecurity/SecurityAutoConfigurationExcluderSpec.groovy
@@ -18,6 +18,7 @@
  */
 package grails.plugin.springsecurity
 
+import org.springframework.core.env.Environment
 import spock.lang.Specification
 import spock.lang.Subject
 import spock.lang.Unroll
@@ -147,6 +148,59 @@ class SecurityAutoConfigurationExcluderSpec extends 
Specification {
         thrown(UnsupportedOperationException)
     }
 
+    def "match allows all auto-configurations when disabled via environment 
property"() {
+        given:
+        Environment env = Mock(Environment)
+        env.getProperty(SecurityAutoConfigurationExcluder.ENABLED_PROPERTY, 
Boolean, true) >> false
+        excluder.setEnvironment(env)
+
+        and:
+        String[] autoConfigs = [
+                
'org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration',
+                
'org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration',
+                
'org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration',
+        ] as String[]
+
+        when:
+        boolean[] results = excluder.match(autoConfigs, null)
+
+        then: 'all auto-configurations pass through when filter is disabled'
+        results[0]
+        results[1]
+        results[2]
+    }
+
+    def "match excludes by default when environment has no property set"() {
+        given:
+        Environment env = Mock(Environment)
+        env.getProperty(SecurityAutoConfigurationExcluder.ENABLED_PROPERTY, 
Boolean, true) >> true
+        excluder.setEnvironment(env)
+
+        and:
+        String[] autoConfigs = [
+                
'org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration',
+        ] as String[]
+
+        when:
+        boolean[] results = excluder.match(autoConfigs, null)
+
+        then: 'exclusion is active by default'
+        !results[0]
+    }
+
+    def "match excludes by default when no environment is set"() {
+        given: 'excluder without environment (e.g. unit test usage)'
+        String[] autoConfigs = [
+                
'org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration',
+        ] as String[]
+
+        when:
+        boolean[] results = excluder.match(autoConfigs, null)
+
+        then: 'exclusion is active by default'
+        !results[0]
+    }
+
     def "spring.factories registers the filter correctly"() {
         when: 'enumerating all spring.factories resources on the classpath'
         Enumeration<URL> resources = 
getClass().getClassLoader().getResources('META-INF/spring.factories')

Reply via email to