Skip to content

Fail fast when spring-security-access is missing - #19460

Open
jyx-07 wants to merge 1 commit into
spring-projects:mainfrom
jyx-07:gh-19441
Open

Fail fast when spring-security-access is missing#19460
jyx-07 wants to merge 1 commit into
spring-projects:mainfrom
jyx-07:gh-19441

Conversation

@jyx-07

@jyx-07 jyx-07 commented Jul 20, 2026

Copy link
Copy Markdown

Summary

Fixes #19441.

spring-security-config's deprecated legacy method-security support throws a raw NoClassDefFoundError at startup instead of a clear error when spring-security-access isn't on the classpath.

Root cause

#17847 moved MethodSecurityMetadataSourceAdvisor and MethodSecurityInterceptor from spring-security-core (a mandatory dependency of spring-security-config) into the new spring-security-access module, which spring-security-config only depends on optionally. Several deprecated method-security paths still construct these types unconditionally:

  • GlobalMethodSecuritySelectorMethodSecurityMetadataSourceAdvisorRegistrar (proxy mode) and GlobalMethodSecurityConfiguration (imported for both proxy and aspectj mode)
  • ReactiveMethodSecuritySelectorReactiveMethodSecurityConfiguration (@EnableReactiveMethodSecurity(useAuthorizationManager = false))

@EnableMethodSecurity and @EnableReactiveMethodSecurity's default mode — the non-deprecated replacements — never reference these classes and are unaffected.

Fix

Added a ClassUtils.isPresent(...) guard (the same pattern already used for other optional dependencies in these selectors) so the legacy paths fail fast with a clear IllegalStateException naming the missing dependency, instead of a NoClassDefFoundError deep in Spring's configuration-processing machinery.

Chose this over making spring-security-access mandatory again, since that would silently reintroduce the footprint #17847 removed for the majority of apps using @EnableMethodSecurity. @EnableGlobalMethodSecurity stays deprecated; this adds no new investment in it beyond a clear diagnostic.

Testing

Added Gh19441Tests, using the existing @ClassPathExclusions harness to simulate spring-security-access being absent:

  • @EnableMethodSecurity and @EnableReactiveMethodSecurity default mode start cleanly (locks in that the modern paths are unaffected).
  • @EnableGlobalMethodSecurity in proxy mode, aspectj mode, and @EnableReactiveMethodSecurity(useAuthorizationManager = false) all now fail with the clear message instead of NoClassDefFoundError/ClassNotFoundException.

Full spring-security-config suite passes (3640 tests; the only 3 failures are pre-existing, locale-related, and unrelated to this change). ./gradlew :spring-security-config:check passes.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jul 20, 2026
@jyx-07 jyx-07 changed the title Guard legacy method security for missing access Fail fast when spring-security-access is missing Jul 20, 2026
The "Move Core Access API" refactoring (spring-projectsgh-17847) relocated
MethodSecurityMetadataSourceAdvisor and MethodSecurityInterceptor
from spring-security-core, a mandatory dependency of
spring-security-config, into the new spring-security-access module,
which spring-security-config only depends on optionally.

GlobalMethodSecuritySelector (backing the deprecated
@EnableGlobalMethodSecurity) and ReactiveMethodSecuritySelector
(backing @EnableReactiveMethodSecurity(useAuthorizationManager =
false)) still unconditionally import configuration that constructs
those classes: MethodSecurityMetadataSourceAdvisorRegistrar in proxy
mode, GlobalMethodSecurityConfiguration in both proxy and aspectj
mode, and ReactiveMethodSecurityConfiguration for the legacy reactive
path. Applications that use any of these deprecated configuration
paths without explicitly adding spring-security-access now fail at
startup with a confusing NoClassDefFoundError deep inside Spring's
configuration-processing machinery, instead of an actionable message.

@EnableMethodSecurity and @EnableReactiveMethodSecurity's default
(AuthorizationManager-based) mode, the non-deprecated replacements,
never reference these classes and are unaffected either way.

Add a ClassUtils.isPresent check to both selectors so that, whenever
a legacy configuration path that needs it is chosen (proxy mode,
aspectj mode, or the legacy reactive interceptor), a missing
spring-security-access dependency now fails fast with a clear
IllegalStateException that names the missing dependency and points
to the supported alternative, rather than a NoClassDefFoundError.

This preserves spring-projectsgh-17847's footprint-reduction intent: the check only
runs for the deprecated legacy annotations, so the majority of
applications using @EnableMethodSecurity see no change in behavior or
dependencies. @EnableGlobalMethodSecurity remains deprecated; this
change adds no new investment in it beyond giving existing users of
it a clear diagnostic instead of a confusing crash.

Closes spring-projectsgh-19441

Signed-off-by: jyx-07 <s25069@gsm.hs.kr>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: waiting-for-triage An issue we've not yet triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NoClassDefFoundError: MethodSecurityMetadataSourceAdvisor missing from spring-security-core 7.1.0 but still referenced by spring-security-config

2 participants