|
4 | 4 | Spring Security 6.4 provides a number of new features.
|
5 | 5 | 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.
|
6 | 6 |
|
7 |
| -- https://github.com/spring-projects/spring-security/issues/4186[gh-4186] - Support `RoleHierarchy` in `AclAuthorizationStrategyImpl` |
8 |
| -- https://github.com/spring-projects/spring-security/issues/15136[gh-15136] - Support `RoleHierarchy` Bean in `authorizeHttpRequests` Kotlin DSL |
| 7 | +== Method Security |
9 | 8 |
|
| 9 | +* 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`] |
| 10 | +* `@AuthenticationPrincipal` and `@CurrentSecurityContext` now support xref:servlet/authorization/method-security.adoc#_templating_meta_annotation_expressions[annotation templates]. |
| 11 | ++ |
| 12 | +This means that you can now use Spring's meta-annotation support like so: |
| 13 | ++ |
| 14 | +[tabs] |
| 15 | +====== |
| 16 | +Java:: |
| 17 | ++ |
| 18 | +[source,java,role="primary"] |
| 19 | +---- |
| 20 | +@Target(TargetType.TYPE) |
| 21 | +@Retention(RetentionPolicy.RUNTIME) |
| 22 | +@AuthenticationPrincipal("claims['{claim}']") |
| 23 | +@interface CurrentUsername { |
| 24 | + String claim() default "sub"; |
| 25 | +} |
| 26 | +
|
| 27 | +// ... |
| 28 | +
|
| 29 | +@GetMapping |
| 30 | +public String method(@CurrentUsername("username") String username) { |
| 31 | + // ... |
| 32 | +} |
| 33 | +---- |
| 34 | +
|
| 35 | +Kotlin:: |
| 36 | ++ |
| 37 | +[source,kotlin,role="secondary"] |
| 38 | +---- |
| 39 | +annotation CurrentUsername(val claim: String = "sub") |
| 40 | +
|
| 41 | +// ... |
| 42 | +
|
| 43 | +@GetMapping |
| 44 | +fun method(@CurrentUsername("username") val username: String): String { |
| 45 | + // ... |
| 46 | +} |
| 47 | +---- |
| 48 | +====== |
| 49 | +* 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. |
| 50 | +This aids in migration from earlier versions of Spring Security. |
| 51 | + |
| 52 | +== OAuth 2.0 |
| 53 | + |
| 54 | +* `oauth2Login()` now accepts https://github.com/spring-projects/spring-security/pull/15237[`OAuth2AuthorizationRequestResolver` as a `@Bean`] |
| 55 | +* OIDC Back-Channel support now accepts https://github.com/spring-projects/spring-security/issues/15003[logout tokens of type `logout+jwt`] |
| 56 | + |
| 57 | +== SAML 2.0 |
| 58 | + |
| 59 | +* Added xref:servlet/saml2/opensaml.adoc[OpenSAML 5 Support]. |
| 60 | +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. |
| 61 | +* Using EntityIDs for the `registrationId` is simplified. |
| 62 | ++ |
| 63 | +A common pattern is to identify asserting parties by their `entityID`. |
| 64 | +In previous versions, this required directly configuring `OpenSamlAuthenticationRequestResolver`. |
| 65 | +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. |
| 66 | +This allows you to use `RelyingPartyRegistrations` or `OpenSaml4/5AssertingPartyMetadataRepository` without also needing to modify the `registrationId` values or customize the request resolver. |
| 67 | ++ |
| 68 | +Relatedly, you can now configure your `authenticationRequestUri` to xref:servlet/saml2/login/authentication-requests.adoc#configuring-authentication-request-uri[contain a query parameter] |
| 69 | +* Asserting Parties can now be refreshed in the background according to the metadata's expiry. |
| 70 | ++ |
| 71 | +For example, you can now use xref:servlet/saml2/metadata.adoc#using-assertingpartymetadatarepository[`OpenSaml5AssertingPartyMetadataRepository`] to do: |
| 72 | ++ |
| 73 | +[tabs] |
| 74 | +====== |
| 75 | +Java:: |
| 76 | ++ |
| 77 | +[source,java,role="primary"] |
| 78 | +---- |
| 79 | +@Component |
| 80 | +public class RefreshableRelyingPartyRegistrationRepository implements IterableRelyingPartyRegistrationRepository { |
| 81 | + private final AssertingPartyMetadataRepository assertingParties = OpenSaml5AssertingPartyMetadataRepository |
| 82 | + .fromTrustedMetadataLocation("https://idp.example.org").build(); |
| 83 | +
|
| 84 | + @Override |
| 85 | + public RelyingPartyRegistration findByRegistrationId(String registrationId) { |
| 86 | + AssertingPartyMetadata assertingParty = this.assertingParties.findByEntityId(registrationId); |
| 87 | + return RelyingPartyRegistration.withAssertingPartyMetadata(assertingParty) |
| 88 | + // relying party configurations |
| 89 | + .build(); |
| 90 | + } |
| 91 | +
|
| 92 | + // ... |
| 93 | +} |
| 94 | +---- |
| 95 | +
|
| 96 | +Kotlin:: |
| 97 | ++ |
| 98 | +[source,kotlin,role="secondary"] |
| 99 | +---- |
| 100 | +@Component |
| 101 | +open class RefreshableRelyingPartyRegistrationRepository: IterableRelyingPartyRegistrationRepository { |
| 102 | + private val assertingParties: AssertingPartyMetadataRepository = OpenSaml5AssertingPartyMetadataRepository |
| 103 | + .fromTrustedMetadataLocation("https://idp.example.org").build() |
| 104 | +
|
| 105 | + override fun findByRegistrationId(String registrationId): RelyingPartyRegistration { |
| 106 | + val assertingParty = this.assertingParties.findByEntityId(registrationId) |
| 107 | + return RelyingPartyRegistration.withAssertingPartyMetadata(assertingParty) |
| 108 | + // relying party configurations |
| 109 | + .build() |
| 110 | + } |
| 111 | +
|
| 112 | + // ... |
| 113 | +} |
| 114 | +---- |
| 115 | +====== |
| 116 | ++ |
| 117 | +This implementation also supports the validation of a metadata's signature. |
| 118 | +* You can now sign https://github.com/spring-projects/spring-security/pull/14916[relying party metadata] |
| 119 | +* `RelyingPartyRegistrationRepository` results can now be javadoc:org.springframework.security.saml2.provider.service.registration.CachingRelyingPartyRegistrationRepository[cached]. |
| 120 | +This is helpful if you want to defer the loading of the registration values til after application startup. |
| 121 | +It is also helpful if you want to control when metadata gets refreshed. |
| 122 | +* 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] |
| 123 | + |
| 124 | +== Web |
| 125 | + |
| 126 | +* CSRF BREACH tokens are now https://github.com/spring-projects/spring-security/issues/15187[more consistent] |
| 127 | +* The Remember Me cookie now is https://github.com/spring-projects/spring-security/pull/15203[more customizable] |
| 128 | +* Security Filter Chain is now improved. |
| 129 | +Specifically, the following arrangement is invalid since an any request filter chain comes before all other filter chains: |
| 130 | ++ |
| 131 | +[tabs] |
| 132 | +====== |
| 133 | +Java:: |
| 134 | ++ |
| 135 | +[source,java,role="primary"] |
| 136 | +---- |
| 137 | +@Bean |
| 138 | +@Order(0) |
| 139 | +SecurityFilterChain api(HttpSecurity http) throws Exception { |
| 140 | + http |
| 141 | + .authorizeHttpRequests(...) |
| 142 | + .httpBasic(...) |
| 143 | +
|
| 144 | + return http.build(); |
| 145 | +} |
| 146 | +
|
| 147 | +@Bean |
| 148 | +@Order(1) |
| 149 | +SecurityFilterChain app(HttpSecurity http) throws Exception { |
| 150 | + http |
| 151 | + .securityMatcher("/app/**") |
| 152 | + .authorizeHttpRequests(...) |
| 153 | + .formLogin(...) |
| 154 | +
|
| 155 | + return http.build(); |
| 156 | +} |
| 157 | +---- |
| 158 | +
|
| 159 | +Kotlin:: |
| 160 | ++ |
| 161 | +[source,kotlin,role="secondary"] |
| 162 | +---- |
| 163 | +@Bean |
| 164 | +@Order(0) |
| 165 | +fun api(val http: HttpSecurity): SecurityFilterChain { |
| 166 | + http { |
| 167 | + authorizeHttpRequests { |
| 168 | + // ... |
| 169 | + } |
| 170 | + } |
| 171 | + return http.build(); |
| 172 | +} |
| 173 | +
|
| 174 | +@Bean |
| 175 | +@Order(1) |
| 176 | +fun app(val http: HttpSecurity): SecurityFilterChain { |
| 177 | + http { |
| 178 | + securityMatcher("/app/**") |
| 179 | + authorizeHttpRequests { |
| 180 | + // ... |
| 181 | + } |
| 182 | + } |
| 183 | + return http.build(); |
| 184 | +} |
| 185 | +---- |
| 186 | +====== |
| 187 | +You can read more https://github.com/spring-projects/spring-security/issues/15220[in the related ticket]. |
| 188 | + |
| 189 | +== Kotlin |
| 190 | + |
| 191 | +* 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 |
| 192 | +* `@PreFilter` and `@PostFilter` are https://github.com/spring-projects/spring-security/pull/15095[now supported] in Kotlin |
| 193 | +* The Kotlin Reactive DSL now supports https://github.com/spring-projects/spring-security/pull/15013[`SecurityContextRepository`] |
| 194 | + |
| 195 | +== Acl |
| 196 | + |
| 197 | +* `AclAuthorizationStrategyImpl` now https://github.com/spring-projects/spring-security/issues/4186[supports `RoleHierarchy`] |
0 commit comments