# 11 — What changed in Spring Security 7 [← production checklist](10-production-checklist.md) · [README](../README.md) 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: ```json "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](output/resource-server-loose.txt) 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 ```java 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(..)`**, not `jwsAlgorithm(..)` — while the *decoder* builders use `macAlgorithm(..)` and `signatureAlgorithm(..)`; - there is **no `keyId(..)`**. Set `kid` through `jwkPostProcessor(jwk -> jwk.keyID(..))`. The pre-7.0 form still compiles: ```java new NimbusJwtEncoder(new ImmutableSecret<>(secretKey)); ``` `setJwkSelector(List::getFirst)` (6.5+) resolves the "multiple matching JWKs" exception. ## Three sibling classes, three packages ```java 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](https://ankurm.com/jackson-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](08-testing.md) ## Boot 4.1: SpEL authority extraction ```yaml 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 ```java .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]) — the `RestClient`-based replacement for the `RestTemplate` introspector, for opaque rather than JWT tokens. - `ConditionalAuthorizationManager` and `AllRequiredFactorsAuthorizationManager.anyOf` ([gh-18960]). - `PreFlightRequestFilter` CORS 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](https://ankurm.com/spring-security-5-to-6-to-7-migration-guide/). [gh-18755]: https://github.com/spring-projects/spring-security/issues/18755 [gh-18745]: https://github.com/spring-projects/spring-security/issues/18745 [gh-18960]: https://github.com/spring-projects/spring-security/issues/18960 [gh-18926]: https://github.com/spring-projects/spring-security/issues/18926 [gh-18634]: https://github.com/spring-projects/spring-security/pull/18634 [gh-18113]: https://github.com/spring-projects/spring-security/issues/18113