feat(security): Spring Security 6 parity — Tier 1 authentication spine (26.6.30)#38
Merged
Merged
Conversation
added 7 commits
June 19, 2026 12:27
AuthenticationManager / ProviderManager / AuthenticationProvider — the Rust analog of Spring's authentication architecture. AuthenticationRequest is a #[non_exhaustive] enum (UsernamePassword / BearerToken) standing in for Spring's pre-auth token; ProviderManager tries each supporting provider in order, first success wins, provider-not-found otherwise. BearerTokenAuthenticationProvider adapts the existing Verifier so JWT/JWKS verifiers slot into the spine. +5 tests; security lib 99 green; clippy + fmt clean.
Spring's recommended {id}-prefixed password storage: DelegatingPasswordEncoder
hashes with a default encoder and prefixes {id} ({bcrypt}$2b$…), verify()
reads the {id} and delegates, and upgrade_encoding() flags a stored hash for
re-encoding on next login when its {id} differs from the default or it is a
legacy unprefixed hash. with_defaults() = {bcrypt} default + {argon2} + {noop},
with bare/legacy hashes verified as bcrypt for seamless migration.
NoOpPasswordEncoder ({noop}) for tests/dev.
+5 tests; security lib 104 green; clippy + fmt clean.
UserDetails (stored credential + the four Spring account-status flags), UserDetailsService (load_user_by_username -> Option), UserDetailsChecker + AccountStatusUserDetailsChecker (locked/disabled/expired), InMemoryUserDetails- Service, and DaoAuthenticationProvider — an AuthenticationProvider for the UsernamePassword request that loads the user, runs the status checks, verifies via a PasswordEncoder, and checks credentials expiry. Enumeration-safe: an unknown user and a wrong password both fail as 'Bad credentials' with comparable encoder work. Plugs into the ProviderManager spine alongside the bearer provider. +4 tests; security lib 108 green; clippy + fmt clean.
SecurityContextRepository (load/save/contains) — Spring's pluggable between-request context store — with HttpSessionSecurityContextRepository (default; configurable session key, wire-compatible with the OAuth2/OTT/WebAuthn handlers) and NullSecurityContextRepository (stateless). SessionAuthenticationLayer now loads the context through a (swappable) repository instead of a hardcoded session key; added Authentication::is_authenticated(). Restore-semantics tests moved to the repository module. +4 repo tests; full security suite (107 lib + integration) green; clippy + fmt clean.
…T1.5) AuthenticationEventPublisher (AuthenticationEvent::Success/Failure) wired into ProviderManager — publishes every authentication outcome (with the attempted username on failure); LoggingAuthenticationEventPublisher default. Completes the authentication-manager spine. ExceptionTranslationFilter seam: AuthenticationEntryPoint (401) + AccessDenied- Handler (403) traits with the canonical problem+json defaults; FilterChain gains with_authentication_entry_point / with_access_denied_handler so a deployment can customise the rejection (login redirect, WWW-Authenticate, etc.). +2 tests; full security suite (109 lib + integration) green; clippy + fmt clean.
… version 26.6.30 CHANGELOG 26.6.30 (Tier 1: AuthenticationManager spine, UserDetails+DAO, DelegatingPasswordEncoder, SecurityContextRepository, auth events, pluggable entry-point/access-denied). Spring Security Parity appendix (EN+ES) marks the authentication-spine row + roadmap tier as done; designed book rebuilt (EN+ES). Workspace bumped to 26.6.30.
- [MED] DaoAuthenticationProvider: the not-found timing-mitigation dummy hash
now falls back to a valid bcrypt hash if the configured encoder's hash()
fails, so the user-enumeration timing equalization can't silently collapse to
an empty (instant-fail) hash under a misconfigured encoder.
- Test gaps closed: SecurityContextRepository seam on SessionAuthenticationLayer
(NullSecurityContextRepository swap), Authentication::is_authenticated, DAO
backend-error propagation, HttpSession typed-object load fallback, and the
bearer (username:None) failure event.
- Documented the remaining by-design/refinement findings (ProviderManager
account-status short-circuit, upgrade_encoding {id}-only, {noop}/unprefixed
defaults) as Known limitations in the 26.6.30 CHANGELOG.
+4 tests; full security suite (113 lib + integration) green; clippy + fmt clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Spring Security 6 parity — Tier 1: the authentication spine
The core of Spring Security's authentication architecture — the foundation later
tiers build on. Additive: no behaviour change to existing code (the default
build and all existing suites are untouched). Release
26.6.30.Follows Tier 0 (#37). See the updated Spring Security Parity book appendix.
Added
AuthenticationManager/ProviderManager/
AuthenticationProvider;AuthenticationRequest(UsernamePassword/BearerToken,#[non_exhaustive]);BearerTokenAuthenticationProvideradaptsthe existing
Verifierinto the spine.UserDetails+ DAO authentication —UserDetails(four account-statusflags),
UserDetailsService,UserDetailsChecker/AccountStatusUserDetailsChecker,InMemoryUserDetailsService, and anenumeration-safe
DaoAuthenticationProvider.DelegatingPasswordEncoder— Spring's{id}-prefixed storage(
{bcrypt}/{argon2}/{noop}) withupgrade_encodingre-hash-on-login andlegacy bare-hash migration;
NoOpPasswordEncoder.SecurityContextRepository— pluggable between-request context store(
HttpSessionSecurityContextRepositorydefault,NullSecurityContextRepositorystateless);
SessionAuthenticationLayernow loads through a swappable repo.AuthenticationEventPublisher— success/failure events fromProviderManager.AuthenticationEntryPoint/AccessDeniedHandler— theExceptionTranslationFilterseam onFilterChain(defaults to problem+json).Verification
firefly-security94 → 113 lib tests + all integrationsuites green;
clippy+cargo fmt --checkclean;reactive-bankingsamplee2e gate green (no regression from the
FilterChain/session_authchanges).substantive one (a not-found timing-mitigation degradation under a
misconfigured encoder) is fixed, test gaps are closed, and the by-design /
refinement findings are documented as Known limitations in the CHANGELOG.
🤖 Generated with Claude Code