Three modules on Spring Boot 4.1.1 with Spring Authorization Server 7.1.1: the provider
itself, a relying party, and an API that trusts its tokens. Client registration, PKCE,
a custom consent page and token customisation, with profiles that make each failure
reproducible.
Every claim is backed by captured output in docs/output/as-*.txt, regenerated by
authorization-server/scripts/run-all.sh. Notable findings, verified against the jars:
- OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(HttpSecurity) was deleted
in 7.0, and both configuration classes moved into spring-security-config
- ClientSettings.requireProofKey flipped from false to true, on the authorization server
(1.5.8 -> 7.1.1) and on the OAuth2 client (6.5.1 -> 7.1.1)
- requireProofKey(false) does not make PKCE optional for a public client; the code
verifier is that client's only authentication at the token endpoint
- MediaTypeRequestMatcher(TEXT_HTML) matches Accept: */*, so the token endpoint answers
API callers with 302 -> /login unless setIgnoredMediaTypes(ALL) is called
Also renames the repository to spring-auth-demo and cross-links the new chapter set from
the existing documentation.
6.2 KiB
11 — What changed in Spring Security 7
← production checklist · next: issuer and audience →
Everything below was hit while building this repository against Spring Security 7.1.1 on Spring Boot 4.1.1, JDK 25. Verified by compiling or by reading real responses, not from release notes alone.
FACTOR_BEARER in your authorities
Every bearer-token authentication now carries an extra authority:
"authorities": ["FACTOR_BEARER", "ROLE_USER", "SCOPE_profile:read"]
It backs the new multi-factor authorization support —
AuthorizationManagerFactories.multiFactor(), @EnableMultiFactorAuthentication, and in
7.1 the when / withWhen conditions and MultiFactorCondition.WEBAUTHN_REGISTERED.
Harmless until a test asserts an exact authority set, or code assumes every authority
starts with ROLE_ or SCOPE_.
resource_metadata in every WWW-Authenticate
WWW-Authenticate: Bearer realm="jwt-auth-demo",
resource_metadata="http://localhost:8080/.well-known/oauth-protected-resource"
Spring Security 7 adds OAuth2ProtectedResourceMetadataFilter to the resource-server
chain — RFC 9728, OAuth 2.0 Protected Resource Metadata. Visible in the
resource-server chain and in the entry point's output
even on the manual profile, because BearerTokenAuthenticationEntryPoint emits it.
7.1 additionally includes charset in WWW-Authenticate (gh-18755).
NimbusJwtEncoder builders (7.0+) and their method names
NimbusJwtEncoder.withSecretKey(secretKey).algorithm(MacAlgorithm.HS256).build();
NimbusJwtEncoder.withKeyPair(rsaPublic, rsaPrivate).algorithm(SignatureAlgorithm.RS256).build();
NimbusJwtEncoder.withKeyPair(ecPublic, ecPrivate).build();
Two traps:
- the builder method is
algorithm(..), notjwsAlgorithm(..)— while the decoder builders usemacAlgorithm(..)andsignatureAlgorithm(..); - there is no
keyId(..). SetkidthroughjwkPostProcessor(jwk -> jwk.keyID(..)).
The pre-7.0 form still compiles:
new NimbusJwtEncoder(new ImmutableSecret<>(secretKey));
setJwkSelector(List::getFirst) (6.5+) resolves the "multiple matching JWKs" exception.
Three sibling classes, three packages
org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint
org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler
org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter
Auto-import will confidently pick the wrong one. This cost a compile cycle here.
Jackson 3
Spring Security 7 moves to Jackson 3 (tools.jackson.*). SecurityJackson2Modules is
replaced by SecurityJacksonModules with JsonMapper.Builder. Boot 4.1.1 resolves
tools.jackson.core:jackson-databind:3.1.5. If you serialise a SecurityContext — into
a session store, a cache, a Redis-backed denylist — that code changes. See the
Jackson 2 to 3 migration guide.
Boot 4 test slices moved
@AutoConfigureMockMvc is now org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc,
in spring-boot-starter-webmvc-test. Security test support is in
spring-boot-starter-security-test. spring-boot-starter-test alone no longer suffices.
→ doc 08
Boot 4.1: SpEL authority extraction
spring:
security:
oauth2:
resourceserver:
jwt:
authorities-claim-expressions: "['realm_access']['roles']"
authority-prefix: "ROLE_"
Mutually exclusive with authorities-claim-name / authorities-claim-delimiter. This is
the property-only answer to Keycloak-style nested role claims, which previously needed a
custom converter.
csrf.spa() is new in 7.0
.csrf(csrf -> csrf.spa())
One call for CookieCsrfTokenRepository + XorCsrfTokenRequestAttributeHandler +
deferred token loading. Checked against the jars: absent from spring-security-config
6.4.7 and 6.5.1, present in 7.0.0. Several guides describe it as a 6.x feature.
Other 7.1 additions worth knowing
RestClientOpaqueTokenIntrospector(gh-18745) — theRestClient-based replacement for theRestTemplateintrospector, for opaque rather than JWT tokens.ConditionalAuthorizationManagerandAllRequiredFactorsAuthorizationManager.anyOf(gh-18960).PreFlightRequestFilterCORS support (gh-18926).InetAddressMatcher(gh-18634).- WebAuthn now publishes authentication events (gh-18113).
Migrating from 6.x
Spring Security's own advice: go to 6.5 first, use its opt-in switches to adopt the 7.0 behaviours one at a time, then upgrade. The 6.5 preparation steps exist precisely so that the 7.0 jump is a version bump rather than a rewrite.
ankurm.com has a dedicated Spring Security 5 → 6 → 7 migration guide.
Two more 7.x changes surfaced while building the authorization-server project, both verified by reading the jars rather than the release notes:
ClientSettings.requireProofKeyflipped fromfalsetotrueon both the authorization server and the OAuth2 client —authorization-server/03OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(HttpSecurity)was deleted, and its class moved intospring-security-config—authorization-server/02
FactorGrantedAuthority now appears in every authority list, and WWW-Authenticate carries
an RFC 9728 resource_metadata parameter —
authorization-server/06.