@groovy.transform.CompileStatic @groovy.util.logging.Slf4j class SecurityAutoConfigurationExcluder extends java.lang.Object implements AutoConfigurationImportFilter, EnvironmentAware
Automatically excludes Spring Boot security auto-configuration classes that conflict with the Grails Spring Security plugin.
The Grails Spring Security plugin owns the servlet security stack of a
Grails application: it builds its own FilterChainProxy
(springSecurityFilterChain), UserDetailsService
(GormUserDetailsService), and request-mapping/access-decision
infrastructure from the grails.plugin.springsecurity.* configuration
namespace.
Spring Boot ships its own auto-configurations that try to do the same job
from the spring.security.* configuration namespace. When both are
active, Spring Boot can register an additional SecurityFilterChain,
an in-memory UserDetailsService, OAuth2 client/authorization-server
filter chains, etc., resulting in two parallel servlet security stacks with
no defined precedence between them.
Configuration contract: while this filter is enabled
(the default), grails.plugin.springsecurity.* is the authoritative
configuration source for the application's security. Boot's
spring.security.* properties are not merged into the plugin
configuration and are not applied by Boot's auto-configuration.
Use the plugin's keys, not Spring Boot's, to configure security when this
plugin is active.
Spring Security 5.7 deprecated and Spring Security 6 removed
WebSecurityConfigurerAdapter, replacing it with a component-based
configuration model that registers individual @Bean components
(see
Spring Security without the WebSecurityConfigurerAdapter).
This plugin pre-dates that model and provides equivalent functionality
through the grails.plugin.springsecurity.* configuration namespace,
but it now blends the most common component-based patterns
automatically via ComponentBasedConfigBlender.
This means you can configure security from either side (or both) and the
effective configuration is the union of both sources.
The following table summarises how each component-based pattern is blended with the plugin's configuration:
@Bean SecurityFilterChain - user-defined
SecurityFilterChain beans are auto-merged
into the plugin's FilterChainProxy. User chains are prepended
(higher precedence) so their typically more-specific request matchers
win against the plugin's catch-all chain. Disable via
grails.plugin.springsecurity.componentBased.autoMergeSecurityFilterChain: false.@Bean WebSecurityCustomizer - still a no-op.
The plugin does not use Spring's WebSecurity builder. To
exclude URLs from security checks, use
grails.plugin.springsecurity.ipRestrictions or
grails.plugin.springsecurity.staticRules with
permitAll access.@Bean AuthenticationManager - the plugin
registers an authenticationManager bean (a
ProviderManager). A user-defined bean with the same name
will fail with a duplicate-bean error. To plug in custom
authentication providers, define @Bean AuthenticationProvider
beans (auto-merged - see the next entry) or add their bean names to
grails.plugin.springsecurity.providerNames.@Bean AuthenticationProvider - user-defined
AuthenticationProvider beans are auto-merged
into the plugin's authenticationManager. User providers are
appended so the plugin's primary GORM-backed provider runs first;
providers already in the manager (e.g. those declared via
providerNames) are not re-added. Disable via
grails.plugin.springsecurity.componentBased.autoMergeAuthenticationProviders: false.@Bean UserDetailsManager /
InMemoryUserDetailsManager /
JdbcUserDetailsManager - for each additional
UserDetailsService bean, a new
DaoAuthenticationProvider is created and appended to the
plugin's authenticationManager providers list. The plugin's
primary GORM-backed provider runs first; if it does not authenticate
the user, each additional provider is tried in turn. (We cannot
rewire the existing daoAuthenticationProvider because Spring
Security 7 made its userDetailsService a final
constructor-only field.) Disable via
grails.plugin.springsecurity.componentBased.autoChainUserDetailsServices: false.spring.security.user.name /
spring.security.user.password /
spring.security.user.roles - if
spring.security.user.name is set, an
InMemoryUserDetailsManager is created from those properties
(mimicking what Spring Boot's
UserDetailsServiceAutoConfiguration would have done), wrapped
in a DaoAuthenticationProvider and added to the plugin's
authenticationManager. Disable via
grails.plugin.springsecurity.componentBased.bridgeSpringSecurityUserProperties: false.EmbeddedLdapServerContextSourceFactoryBean,
LdapBindAuthenticationManagerFactory,
LdapPasswordComparisonAuthenticationManagerFactory)
- the grails-spring-security-ldap plugin provides equivalent
configuration through grails.plugin.springsecurity.ldap.*.
User-defined LDAP factory beans coexist but are not wired into the
plugin's authentication providers.To delegate the entire servlet security stack to Spring Boot's
component-based model (and stop using the plugin's
grails.plugin.springsecurity.* configuration), disable this filter
- see the "Opt-out" section below.
In Spring Boot 4 the security auto-configurations were moved out of
spring-boot-autoconfigure into dedicated spring-boot-security*
modules and re-packaged under org.springframework.boot.security.*.
Adding any of those starters/modules to a Grails application would otherwise
re-introduce the conflicting servlet auto-configurations. This filter excludes
them during Spring Boot's auto-configuration discovery phase, so users do not
need to maintain a manual spring.autoconfigure.exclude list.
To disable this filter and allow Spring Boot's security auto-configurations
to run (for example, to delegate the entire servlet security stack to Spring
Boot instead of the plugin), set the following property in
application.yml:
grails:
plugin:
springsecurity:
excludeSpringSecurityAutoConfiguration: false
Disabling this filter is intentionally a footgun: the plugin can no longer
guarantee that its filter chain is the only servlet security stack in the
application context, and a startup WARN is logged when it is turned
off.
Registered via META-INF/spring.factories as an
AutoConfigurationImportFilter. This runs before auto-configuration
bytecode is loaded, so there is no performance overhead from excluded classes.
| Type | Name and description |
|---|---|
static java.lang.String |
ENABLED_PROPERTY |
| Constructor and description |
|---|
SecurityAutoConfigurationExcluder() |
| Type Params | Return Type | Name and description |
|---|---|---|
|
static java.util.Set<java.lang.String> |
getExcludedAutoConfigurations()Returns the set of auto-configuration class names that this filter excludes. |
|
boolean[] |
match(java.lang.String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) |
|
void |
setEnvironment(Environment environment) |
| Methods inherited from class | Name |
|---|---|
class java.lang.Object |
java.lang.Object#equals(java.lang.Object), java.lang.Object#getClass(), java.lang.Object#hashCode(), java.lang.Object#notify(), java.lang.Object#notifyAll(), java.lang.Object#toString(), java.lang.Object#wait(), java.lang.Object#wait(long), java.lang.Object#wait(long, int) |
Returns the set of auto-configuration class names that this filter excludes. Exposed for testing and diagnostic purposes.