This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Security 6.3.4! |
What’s New in Spring Security 6.4
Spring Security 6.4 provides a number of new features. Below are the highlights of the release, or you can view the release notes for a detailed listing of each feature and bug fix.
Method Security
-
All method security annotations now support Framework’s
@AliasFor
-
@AuthenticationPrincipal
and@CurrentSecurityContext
now support annotation templates.This means that you can now use Spring’s meta-annotation support like so:
-
Java
-
Kotlin
@Target(TargetType.TYPE) @Retention(RetentionPolicy.RUNTIME) @AuthenticationPrincipal("claims['{claim}']") @interface CurrentUsername { String claim() default "sub"; } // ... @GetMapping public String method(@CurrentUsername("username") String username) { // ... }
annotation CurrentUsername(val claim: String = "sub") // ... @GetMapping fun method(@CurrentUsername("username") val username: String): String { // ... }
-
-
Several improvements were made to align Security’s annotation search with
AbstractFallbackMethodSecurityMetadataSource
's algorithm. This aids in migration from earlier versions of Spring Security.
OAuth 2.0
-
oauth2Login()
now acceptsOAuth2AuthorizationRequestResolver
as a@Bean
-
Added
loginPage()
to DSL in reactiveoauth2Login()
-
OIDC Back-Channel support now accepts logout tokens of type
logout+jwt
-
RestClient
can now be configured withOAuth2ClientHttpRequestInterceptor
to make protected resources requests -
Added
RestClient
-based implementations ofOAuth2AccessTokenResponseClient
for more consistent configuration of access token requests.To opt-in to using
RestClient
support, simply publish a bean for each grant type as in the following example:-
Java
-
Kotlin
@Configuration public class SecurityConfig { @Bean public OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> authorizationCodeAccessTokenResponseClient() { return new RestClientAuthorizationCodeTokenResponseClient(); } @Bean public OAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> refreshTokenAccessTokenResponseClient() { return new RestClientRefreshTokenTokenResponseClient(); } @Bean public OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> clientCredentialsAccessTokenResponseClient() { return new RestClientClientCredentialsTokenResponseClient(); } @Bean public OAuth2AccessTokenResponseClient<JwtBearerGrantRequest> jwtBearerAccessTokenResponseClient() { return new RestClientJwtBearerTokenResponseClient(); } @Bean public OAuth2AccessTokenResponseClient<TokenExchangeGrantRequest> tokenExchangeAccessTokenResponseClient() { return new RestClientTokenExchangeTokenResponseClient(); } }
@Configuration class SecurityConfig { @Bean fun authorizationCodeAccessTokenResponseClient(): OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> { return RestClientAuthorizationCodeTokenResponseClient() } @Bean fun refreshTokenAccessTokenResponseClient(): OAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> { return RestClientRefreshTokenTokenResponseClient() } @Bean fun clientCredentialsAccessTokenResponseClient(): OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> { return RestClientClientCredentialsTokenResponseClient() } @Bean fun jwtBearerAccessTokenResponseClient(): OAuth2AccessTokenResponseClient<JwtBearerGrantRequest> { return RestClientJwtBearerTokenResponseClient() } @Bean fun tokenExchangeAccessTokenResponseClient(): OAuth2AccessTokenResponseClient<TokenExchangeGrantRequest> { return RestClientTokenExchangeTokenResponseClient() } }
-
-
Deprecated
Default*
implementations ofOAuth2AccessTokenResponseClient
SAML 2.0
-
Added OpenSAML 5 Support. Now you can use either OpenSAML 4 or OpenSAML 5; by default, Spring Security will select the write implementations based on what’s on your classpath.
-
Using EntityIDs for the
registrationId
is simplified.A common pattern is to identify asserting parties by their
entityID
. In previous versions, this required directly configuringOpenSamlAuthenticationRequestResolver
. Now, the request resolver looks by default for theregistrationId
as a request parameter in addition to looking for it in the path. This allows you to useRelyingPartyRegistrations
orOpenSaml4/5AssertingPartyMetadataRepository
without also needing to modify theregistrationId
values or customize the request resolver.Relatedly, you can now configure your
authenticationRequestUri
to contain a query parameter -
Asserting Parties can now be refreshed in the background according to the metadata’s expiry.
For example, you can now use
OpenSaml5AssertingPartyMetadataRepository
to do:-
Java
-
Kotlin
@Component public class RefreshableRelyingPartyRegistrationRepository implements IterableRelyingPartyRegistrationRepository { private final AssertingPartyMetadataRepository assertingParties = OpenSaml5AssertingPartyMetadataRepository .fromTrustedMetadataLocation("https://idp.example.org").build(); @Override public RelyingPartyRegistration findByRegistrationId(String registrationId) { AssertingPartyMetadata assertingParty = this.assertingParties.findByEntityId(registrationId); return RelyingPartyRegistration.withAssertingPartyMetadata(assertingParty) // relying party configurations .build(); } // ... }
@Component open class RefreshableRelyingPartyRegistrationRepository: IterableRelyingPartyRegistrationRepository { private val assertingParties: AssertingPartyMetadataRepository = OpenSaml5AssertingPartyMetadataRepository .fromTrustedMetadataLocation("https://idp.example.org").build() override fun findByRegistrationId(String registrationId): RelyingPartyRegistration { val assertingParty = this.assertingParties.findByEntityId(registrationId) return RelyingPartyRegistration.withAssertingPartyMetadata(assertingParty) // relying party configurations .build() } // ... }
This implementation also supports the validation of a metadata’s signature.
-
-
You can now sign relying party metadata
-
RelyingPartyRegistrationRepository
results can now be cached. This is helpful if you want to defer the loading of the registration values til after application startup. It is also helpful if you want to control when metadata gets refreshed. -
To align with the SAML 2.0 standard, the metadata endpoint now uses the
application/samlmetadata+xml
MIME type
Web
-
CSRF BREACH tokens are now more consistent
-
The Remember Me cookie now is more customizable
-
Security Filter Chain is now improved. Specifically, the following arrangement is invalid since an any request filter chain comes before all other filter chains:
-
Java
-
Kotlin
@Bean @Order(0) SecurityFilterChain api(HttpSecurity http) throws Exception { http .authorizeHttpRequests(...) .httpBasic(...) return http.build(); } @Bean @Order(1) SecurityFilterChain app(HttpSecurity http) throws Exception { http .securityMatcher("/app/**") .authorizeHttpRequests(...) .formLogin(...) return http.build(); }
@Bean @Order(0) fun api(val http: HttpSecurity): SecurityFilterChain { http { authorizeHttpRequests { // ... } } return http.build() } @Bean @Order(1) fun app(val http: HttpSecurity): SecurityFilterChain { http { securityMatcher("/app/**") authorizeHttpRequests { // ... } } return http.build() }
You can read more in the related ticket.
-
One-Time Token Login
Spring Security now supports One-Time Token Login via the oneTimeTokenLogin()
DSL.
Passkeys
Spring Security now has Passkeys support.
Kotlin
-
The Kotlin DSL now supports SAML 2.0 and
GrantedAuthorityDefaults
andRoleHierarchy
@Bean
s -
@PreFilter
and@PostFilter
are now supported in Kotlin -
The Kotlin Reactive DSL now supports
SecurityContextRepository
Acl
-
AclAuthorizationStrategyImpl
now supportsRoleHierarchy