Posts Tagged ‘AuthorizationServer’
[SpringIO2026] New in Spring Security 7: MFA, OAuth2 and more
Lecturer
Daniel Garnier-Moiroux is a software engineer on the Spring team at Broadcom, focusing on Spring Security, identity, and SSO concerns. He contributes actively to Spring Security and related projects, including work on one-time tokens, passkeys, multi-factor authentication, and Model Context Protocol security. He is also writing the Manning book Testing Spring Boot Applications (early access). Previously affiliated with VMware Tanzu, he has spoken widely on Spring Security architecture, passwordless authentication, and practical security patterns. He maintains an active presence through his personal site and open-source contributions under the handle Kehrlann.
Abstract
Spring Security 7 delivers a long-requested multi-factor authentication capability together with modular configuration improvements, OAuth 2 enhancements on both the authorization-server and client sides, stricter defaults such as mandatory PKCE, dynamic client registration, and experimental support for securing Model Context Protocol endpoints. This article examines the design of the new MFA APIs built around factor granted authorities and authorization-manager factories, shows how modular customizers avoid overwriting Spring Boot defaults, details the OAuth 2 changes, and outlines migration considerations from version 6.
Multi-Factor Authentication APIs
Multi-factor authentication had been requested since issue 2603 was opened in 2013. Spring Security 7 finally ships first-class support. Authentication factors are modelled as special GrantedAuthority instances of type FactorGrantedAuthority. Each successful login method (password, one-time token, passkey, and so on) records both the factor type and the timestamp at which it was obtained.
The annotation @EnableMultiFactorAuthentication installs the necessary infrastructure and accepts a list of required factors. When the list is supplied at the global level, every protected endpoint demands those factors. For finer control the same requirement can be expressed per endpoint by obtaining an AuthorizationManager from a multi-factor factory:
AuthorizationManagerFactory mfa =
AuthorizationManagerFactories.multiFactor()
.requireFactors(
FactorGrantedAuthority.PASSWORD,
FactorGrantedAuthority.OTT)
.build();
http.authorizeHttpRequests(authz ->
authz.requestMatchers("/admin/**")
.access(mfa.hasRole("ADMIN")));
Because the underlying API is the familiar access(AuthorizationManager), arbitrary combinations become possible. The utility AuthorizationManagers.allOf and anyOf allow mixing recent-password checks with role checks, or applying MFA only to administrators while ordinary users need only a password. Time-based constraints are expressed with AllRequiredFactorsAuthorizationManager and a duration; an authentication older than the chosen window is rejected and the user is forced to re-authenticate with the missing factor.
The design deliberately re-uses the existing authorization infrastructure rather than inventing a parallel authentication pipeline. Consequently any custom AuthorizationManager already written for complex access rules can be composed with factor requirements without further framework changes.
Modular Configuration and Safer Defaults
A common pain point in earlier versions was that declaring a single SecurityFilterChain bean completely replaced Spring Boot’s auto-configured security. Spring Security 7 introduces Customizer<HttpSecurity> (and the corresponding customizers for individual configurers such as OAuth2AuthorizationServerConfigurer or CsrfConfigurer). Applications that need only a small adjustment—making one path public, adding a claim to the OpenID Provider Configuration endpoint, or tweaking CSRF—now supply a focused customizer bean. Boot defaults remain intact and the change is applied on top of them.
Several legacy constructs have been removed or relocated. The classic “and()” DSL that closed configuration blocks is gone; lambda style is mandatory. The OAuth 2 password grant has been dropped from the client because the OAuth 2 security best-current-practice document has long discouraged it. Kerberos support and the Spring Authorization Server project itself have been aligned to the same version numbering as the core Spring Security modules, simplifying release coordination.
OAuth 2 Enhancements on Server and Client
On the authorization-server side PKCE is now required by default. Clients that cannot yet produce a code challenge can disable the requirement, but the recommended posture is to keep it enabled even for confidential clients. Dynamic client registration, driven by the need to support Model Context Protocol agents that self-register, has been added. An admin client holding the client.create scope (or, for the more open MCP use-case, an unauthenticated registration endpoint) can POST a registration request and receive a generated client identifier and secret. Tokens used for registration are single-use, limiting abuse.
On the client side Spring Framework 7’s HTTP service clients receive first-class OAuth 2 support. A single bean of type OAuth2RestClientHttpServiceGroupConfigurer wires an OAuth2AuthorizedClientManager and a client-registration identifier into every declarative HTTP interface. The resulting code is free of manual RestClient interceptors yet still obtains and refreshes tokens automatically.
MCP Security and Migration Guidance
Because the Model Context Protocol specification continues to evolve rapidly, MCP security lives in a dedicated Spring AI community project rather than in core Spring Security. The same team members maintain both, and the intention is to graduate the work once the protocol stabilises. Starters on start.spring.io already expose experimental MCP server and client security options that rely on the OAuth 2 features described above.
Migration from Spring Security 6 is documented in a dedicated guide. Most applications that already use the lambda DSL and modern authorization managers require only dependency updates and the removal of the password-grant client code. Applications still relying on the old access-decision voters must move to the authorization-manager model; the deprecated classes remain available in a separate module for a transitional period.
Taken together, the release strengthens the security baseline while giving developers precise, composable tools for multi-factor scenarios and modern authorization flows.