| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 | [[new]]= What's New in Spring Security 6.3Spring Security 6.3 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.== Passive JDK Serialization SupportWhen it comes to its support for JDK-serialized security components, Spring Security has historically been quite aggressive, supporting each serialization version for only one Spring Security minor version.This meant that if you had JDK-serialized security components, then they would need to be evacuated before upgrading to the next Spring Security version since they would no longer be deserializable.Now that Spring Security performs a minor release every six months, this became a much larger pain point.To address that, Spring Security now will https://spring.io/blog/2024/01/19/spring-security-6-3-adds-passive-jdk-serialization-deserialization-for[maintain passivity with JDK serialization], like it does with JSON serialization, making for more seamless upgrades.== AuthorizationAn ongoing theme for the last several releases has been to refactor and improve Spring Security's authorization subsystem.Starting with replacing the `AccessDecisionManager` API with `AuthorizationManager` it's now come to the point where we are able to add several exciting new features.=== Annotation Parameters - https://github.com/spring-projects/spring-security/issues/14480[#14480]The first 6.3 feature is https://github.com/spring-projects/spring-security/issues/14480[support for annotation parameters].Consider Spring Security's support for xref:servlet/authorization/method-security.adoc#meta-annotations[meta-annotations] like this one:[tabs]======Java::+[source,java,role="primary"]----@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)@PreAuthorize("hasAuthority('SCOPE_message:read')")public @interface HasMessageRead {}----Kotlin::+.Kotlin[source,kotlin,role="secondary"]----@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)@PreAuthorize("hasAuthority('SCOPE_message:read')")annotation class HasMessageRead----======Before this release, something like this is only helpful when it is used widely across the codebase.But now, xref:servlet/authorization/method-security.adoc#_templating_meta_annotation_expressions[you can add parameters] like so:[tabs]======Java::+[source,java,role="primary"]----@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)@PreAuthorize("hasAuthority('SCOPE_{scope}')")public @interface HasScope {	String scope();}----Kotlin::+[source,kotlin,role="secondary"]----@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)@PreAuthorize("hasAuthority('SCOPE_{scope}')")annotation class HasScope (val scope:String)----======making it possible to do things like this:[tabs]======Java::+[source,java,role="primary"]----@HasScope("message:read")public String method() { ... }----Kotlin::+[source,kotlin,role="secondary"]----@HasScope("message:read")fun method(): String { ... }----======and apply your SpEL expression in several more places.=== Secure Return Values - https://github.com/spring-projects/spring-security/issues/14596[#14596], https://github.com/spring-projects/spring-security/issues/14597[#14597]Since the early days of Spring Security, you've been able to xref:servlet/authorization/method-security.adoc#use-preauthorize[annotate Spring beans with `@PreAuthorize` and `@PostAuthorize`].But controllers, services, and repositories are not the only things you care to secure.For example, what about a domain object `Order` where only admins should be able to call the `Order#getPayment` method?Now in 6.3, https://github.com/spring-projects/spring-security/issues/14597[you can annotate those methods], too.First, annotate the `getPayment` method like you would a Spring bean:[tabs]======Java::+[source,java,role="primary"]----public class Order {	@HasScope("payment:read")	Payment getPayment() { ... }}----Kotlin::+[source,kotlin,role="secondary"]----class Order {	@HasScope("payment:read")	fun getPayment(): Payment { ... }}----======And then xref:servlet/authorization/method-security.adoc#authorize-object[annotate your Spring Data repository with `@AuthorizeReturnObject`] like so:[tabs]======Java::+[source,java,role="primary"]----public interface OrderRepository implements CrudRepository<Order, String> {	@AuthorizeReturnObject	Optional<Order> findOrderById(String id);}----Kotlin::+[source,kotlin,role="secondary"]----interface OrderRepository : CrudRepository<Order, String> {    @AuthorizeReturnObject    fun findOrderById(id: String?): Optional<Order?>?}----======At that point, Spring Security will protect any `Order` returned from `findOrderById` by way of https://github.com/spring-projects/spring-security/issues/14596[proxying the `Order` instance].=== Error Handling - https://github.com/spring-projects/spring-security/issues/14598[#14598], https://github.com/spring-projects/spring-security/issues/14600[#14600], https://github.com/spring-projects/spring-security/issues/14601[#14601]In this release, you can also https://github.com/spring-projects/spring-security/issues/14601[intercept and handle failure at the method level] with its last new method security annotation.When you xref:servlet/authorization/method-security.adoc#fallback-values-authorization-denied[annotate a method with `@HandleAuthorizationDenied`] like so:[tabs]======Java::+[source,java,role="primary"]----public class Payment {    @HandleAuthorizationDenied(handlerClass=Mask.class)    @PreAuthorize("hasAuthority('card:read')")    public String getCreditCardNumber() { ... }}----Kotlin::+[source,kotlin,role="secondary"]----class Payment {    @HandleAuthorizationDenied(handlerClass=Mask.class)    @PreAuthorize("hasAuthority('card:read')")    fun getCreditCardNumber(): String { ... }}----======and publish a `Mask` bean:[tabs]======Java::+[source,java,role="primary"]----@Componentpublic class Mask implements MethodAuthorizationDeniedHandler {	@Override    public Object handleDeniedInvocation(MethodInvocation invocation, AuthorizationResult result) {		return "***";    }}----Kotlin::+[source,kotlin,role="secondary"]----@Componentclass Mask : MethodAuthorizationDeniedHandler {    fun handleDeniedInvocation(invocation: MethodInvocation?, result: AuthorizationResult?): Any = "***"}----======then any unauthorized call to `Payment#getCreditCardNumber` will return `\***` instead of the number.You can see all these features at work together in https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/data[the latest Spring Security Data sample].== Compromised Password Checking - https://github.com/spring-projects/spring-security/issues/7395[#7395]If you are going to let users pick passwords, it's critical to ensure that such a password isn't already compromised.Spring Security 6.3 makes this as simple as xref:features/authentication/password-storage.adoc#authentication-compromised-password-check[publishing a `CompromisedPasswordChecker` bean]:[tabs]======Java::+[source,java,role="primary"]----@Beanpublic CompromisedPasswordChecker compromisedPasswordChecker() {    return new HaveIBeenPwnedRestApiPasswordChecker();}----Kotlin::+[source,kotlin,role="secondary"]----@Beanfun compromisedPasswordChecker(): CompromisedPasswordChecker = HaveIBeenPwnedRestApiPasswordChecker()----======== `spring-security-rsa` is now part of Spring Security - https://github.com/spring-projects/spring-security/issues/14202[#14202]Since 2017, Spring Security has been undergoing a long-standing initiative to fold various Spring Security extensions into Spring Security proper.In 6.3, `spring-security-rsa` becomes the latest of these projects which will help the team maintain and add features to it, long-term.`spring-security-rsa` provides a number of https://github.com/spring-projects/spring-security/blob/main/crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaSecretEncryptor.java[handy `BytesEncryptor`] https://github.com/spring-projects/spring-security/blob/main/crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaRawEncryptor.java[implementations] as well as https://github.com/spring-projects/spring-security/blob/main/crypto/src/main/java/org/springframework/security/crypto/encrypt/KeyStoreKeyFactory.java[a simpler API for working with ``KeyStore``s].== OAuth 2.0 Token Exchange Grant - https://github.com/spring-projects/spring-security/issues/5199[#5199]One of https://github.com/spring-projects/spring-security/issues/5199[the most highly-voted OAuth 2.0 features] in Spring Security is now in place in 6.3, which is the support for https://datatracker.ietf.org/doc/html/rfc8693#section-2[the OAuth 2.0 Token Exchange grant].For xref:servlet/oauth2/client/authorization-grants.adoc#token-exchange-grant-access-token[any client configured for token exchange], you can activate it in Spring Security by adding a `TokenExchangeAuthorizedClientProvider` instance to your `OAuth2AuthorizedClientManager` like so:[tabs]======Java::+[source,java,role="primary"]----@Beanpublic OAuth2AuthorizedClientProvider tokenExchange() {	return new TokenExchangeOAuth2AuthorizedClientProvider();}----Kotlin::+[source,kotlin,role="secondary"]----@Beanfun tokenExchange(): OAuth2AuthorizedClientProvider = TokenExchangeOAuth2AuthorizedClientProvider()----======and then xref:servlet/oauth2/client/authorized-clients.adoc#oauth2Client-registered-authorized-client[use the `@RegisteredOAuth2AuthorizedClient` annotation] as per usual to retrieve the appropriate token with the expanded privileges your resource server needs.== Additional Highlights- https://github.com/spring-projects/spring-security/pull/14655[gh-14655] - Add `DelegatingAuthenticationConverter`- https://github.com/spring-projects/spring-security/issues/6192[gh-6192] - Add Concurrent Sessions Control on WebFlux (xref:reactive/authentication/concurrent-sessions-control.adoc[docs])- https://github.com/spring-projects/spring-security/pull/14193[gh-14193] - Added support for CAS Gateway Authentication- https://github.com/spring-projects/spring-security/issues/13259[gh-13259] - Customize when UserInfo is called- https://github.com/spring-projects/spring-security/pull/14168[gh-14168] - Introduce Customizable AuthorizationFailureHandler in OAuth2AuthorizationRequestRedirectFilter- https://github.com/spring-projects/spring-security/issues/14672[gh-14672] - Customize mapping the OidcUser from OidcUserRequest and OidcUserInfo- https://github.com/spring-projects/spring-security/issues/13763[gh-13763] - Simplify configuration of reactive OAuth2 Client component model- https://github.com/spring-projects/spring-security/issues/14758[gh-14758] - Update reactive OAuth2 docs landing page with examples (xref:reactive/oauth2/index.adoc[docs])- https://github.com/spring-projects/spring-security/issues/10538[gh-10538] - Support Certificate-Bound JWT Access Token Validation- https://github.com/spring-projects/spring-security/pull/14265[gh-14265] - Support Nested username in UserInfo response- https://github.com/spring-projects/spring-security/pull/14265[gh-14449] - Add `SecurityContext` argument resolver- https://github.com/spring-projects/spring-security/issues/11440[gh-11440] - Simplify Disabling `application/x-www-form-urlencoded` Encoding Client ID and Secret (xref:servlet/oauth2/client/client-authentication.adoc#_authenticate_using_client_secret_basic[servlet docs], xref:reactive/oauth2/client/client-authentication.adoc#_authenticate_using_client_secret_basic[reactive docs])And for an exhaustive list, please see the release notes for https://github.com/spring-projects/spring-security/releases/tag/6.3.0-RC1[6.3.0-RC1], https://github.com/spring-projects/spring-security/releases/tag/6.3.0-M3[6.3.0-M3], https://github.com/spring-projects/spring-security/releases/tag/6.3.0-M2[6.3.0-M2], and https://github.com/spring-projects/spring-security/releases/tag/6.3.0-M1[6.3.0-M1].
 |