From 06febf785733ed897592078d165b71c2a70731b4 Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Tue, 20 Aug 2024 18:38:02 -0600 Subject: [PATCH] Update What's New --- .../saml2/login/authentication-requests.adoc | 1 + .../ROOT/pages/servlet/saml2/metadata.adoc | 1 + docs/modules/ROOT/pages/whats-new.adoc | 192 +++++++++++++++++- 3 files changed, 192 insertions(+), 2 deletions(-) diff --git a/docs/modules/ROOT/pages/servlet/saml2/login/authentication-requests.adoc b/docs/modules/ROOT/pages/servlet/saml2/login/authentication-requests.adoc index 34ca0d8bc7..d49eea4b60 100644 --- a/docs/modules/ROOT/pages/servlet/saml2/login/authentication-requests.adoc +++ b/docs/modules/ROOT/pages/servlet/saml2/login/authentication-requests.adoc @@ -12,6 +12,7 @@ For example, if you were deployed to `https://rp.example.com` and you gave your and the result would be a redirect that included a `SAMLRequest` parameter containing the signed, deflated, and encoded ``. +[configuring-authentication-request-uri] == Configuring the `` Endpoint To configure the endpoint differently from the default, you can set the value in `saml2Login`: diff --git a/docs/modules/ROOT/pages/servlet/saml2/metadata.adoc b/docs/modules/ROOT/pages/servlet/saml2/metadata.adoc index e4f96a783c..013eb21082 100644 --- a/docs/modules/ROOT/pages/servlet/saml2/metadata.adoc +++ b/docs/modules/ROOT/pages/servlet/saml2/metadata.adoc @@ -32,6 +32,7 @@ val openSamlEntityDescriptor: EntityDescriptor = details.getEntityDescriptor() ---- ====== +[using-assertingpartymetadatarepository] === Using `AssertingPartyMetadataRepository` You can also be more targeted than `RelyingPartyRegistrations` by using `AssertingPartyMetadataRepository`, an interface that allows for only retrieving the asserting party metadata. diff --git a/docs/modules/ROOT/pages/whats-new.adoc b/docs/modules/ROOT/pages/whats-new.adoc index 1453c954ec..fd4ee6ad84 100644 --- a/docs/modules/ROOT/pages/whats-new.adoc +++ b/docs/modules/ROOT/pages/whats-new.adoc @@ -4,6 +4,194 @@ Spring Security 6.4 provides a number of new features. Below are the highlights of the release, or you can view https://github.com/spring-projects/spring-security/releases[the release notes] for a detailed listing of each feature and bug fix. -- https://github.com/spring-projects/spring-security/issues/4186[gh-4186] - Support `RoleHierarchy` in `AclAuthorizationStrategyImpl` -- https://github.com/spring-projects/spring-security/issues/15136[gh-15136] - Support `RoleHierarchy` Bean in `authorizeHttpRequests` Kotlin DSL +== Method Security +* All xref:servlet/authorization/method-security.adoc#using_metannotation-method-interceptors[method security annotations] now support {spring-framework-api-url}org/springframework/core/annotation/AliasFor.html[Framework's `@AliasFor`] +* `@AuthenticationPrincipal` and `@CurrentSecurityContext` now support xref:servlet/authorization/method-security.adoc#_templating_meta_annotation_expressions[annotation templates]. ++ +This means that you can now use Spring's meta-annotation support like so: ++ +[tabs] +====== +Java:: ++ +[source,java,role="primary"] +---- +@Target(TargetType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@AuthenticationPrincipal("claims['{claim}']") +@interface CurrentUsername { + String claim() default "sub"; +} + +// ... + +@GetMapping +public String method(@CurrentUsername("username") String username) { + // ... +} +---- + +Kotlin:: ++ +[source,kotlin,role="secondary"] +---- +annotation CurrentUsername(val claim: String = "sub") + +// ... + +@GetMapping +fun method(@CurrentUsername("username") val username: String): String { + // ... +} +---- +====== +* https://github.com/spring-projects/spring-security/issues/13490[Several] https://github.com/spring-projects/spring-security/issues/13234[improvements] https://github.com/spring-projects/spring-security/issues/15097[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 accepts https://github.com/spring-projects/spring-security/pull/15237[`OAuth2AuthorizationRequestResolver` as a `@Bean`] +* OIDC Back-Channel support now accepts https://github.com/spring-projects/spring-security/issues/15003[logout tokens of type `logout+jwt`] + +== SAML 2.0 + +* Added xref:servlet/saml2/opensaml.adoc[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 configuring `OpenSamlAuthenticationRequestResolver`. +Now, the request resolver looks by default for the `registrationId` https://github.com/spring-projects/spring-security/issues/15017[as a request parameter] in addition to looking for it in the path. +This allows you to use `RelyingPartyRegistrations` or `OpenSaml4/5AssertingPartyMetadataRepository` without also needing to modify the `registrationId` values or customize the request resolver. ++ +Relatedly, you can now configure your `authenticationRequestUri` to xref:servlet/saml2/login/authentication-requests.adoc#configuring-authentication-request-uri[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 xref:servlet/saml2/metadata.adoc#using-assertingpartymetadatarepository[`OpenSaml5AssertingPartyMetadataRepository`] to do: ++ +[tabs] +====== +Java:: ++ +[source,java,role="primary"] +---- +@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(); + } + + // ... +} +---- + +Kotlin:: ++ +[source,kotlin,role="secondary"] +---- +@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 https://github.com/spring-projects/spring-security/pull/14916[relying party metadata] +* `RelyingPartyRegistrationRepository` results can now be javadoc:org.springframework.security.saml2.provider.service.registration.CachingRelyingPartyRegistrationRepository[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 https://github.com/spring-projects/spring-security/issues/15147[uses the `application/samlmetadata+xml` MIME type] + +== Web + +* CSRF BREACH tokens are now https://github.com/spring-projects/spring-security/issues/15187[more consistent] +* The Remember Me cookie now is https://github.com/spring-projects/spring-security/pull/15203[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: ++ +[tabs] +====== +Java:: ++ +[source,java,role="primary"] +---- +@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(); +} +---- + +Kotlin:: ++ +[source,kotlin,role="secondary"] +---- +@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 https://github.com/spring-projects/spring-security/issues/15220[in the related ticket]. + +== Kotlin + +* The Kotlin DSL now supports https://github.com/spring-projects/spring-security/issues/14935[SAML 2.0] and https://github.com/spring-projects/spring-security/issues/15171[`GrantedAuthorityDefaults`] and https://github.com/spring-projects/spring-security/issues/15136[`RoleHierarchy`] ``@Bean``s +* `@PreFilter` and `@PostFilter` are https://github.com/spring-projects/spring-security/pull/15095[now supported] in Kotlin +* The Kotlin Reactive DSL now supports https://github.com/spring-projects/spring-security/pull/15013[`SecurityContextRepository`] + +== Acl + +* `AclAuthorizationStrategyImpl` now https://github.com/spring-projects/spring-security/issues/4186[supports `RoleHierarchy`]