Spring Security 6.3 の新機能
Spring Security 6.3 には、いくつかの新機能があります。以下はリリースのハイライトです。また、各機能とバグ修正の詳細なリストについては、リリースノート [GitHub] (英語) を参照してください。
パッシブ JDK 直列化サポート
JDK 直列化されたセキュリティコンポーネントのサポートに関しては、Spring Security は歴史的にかなり積極的で、各直列化バージョンを 1 つの Spring Security マイナーバージョンのみでサポートしていました。つまり、JDK 直列化されたセキュリティコンポーネントがある場合、デシリアライズできなくなるため、次の Spring Security バージョンにアップグレードする前に退避する必要がありました。
現在、Spring Security は 6 か月ごとにマイナーリリースを実行しているため、これは大きな問題点となっています。これに対処するために、Spring Security は JSON 直列化と同様に JDK 直列化でも受動性を維持し (英語) 、よりシームレスなアップグレードを実現します。
認可
過去数回のリリースで継続中のテーマは、Spring Security の認証サブシステムのリファクタリングと改善です。AccessDecisionManager
API を AuthorizationManager
に置き換えることから始まり、今ではいくつかのエキサイティングな新機能を追加できるようになりました。
アノテーションパラメーター - #14480 [GitHub] (英語)
6.3 の最初の機能は、アノテーションパラメーターのサポート [GitHub] (英語) です。次のような Spring Security のメタアノテーションのサポートについて考えてみましょう。
Java
Kotlin
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@PreAuthorize("hasAuthority('SCOPE_message:read')")
public @interface HasMessageRead {}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@PreAuthorize("hasAuthority('SCOPE_message:read')")
annotation class HasMessageRead
このリリース以前は、このようなものはコードベース全体で広く使用されている場合にのみ役立ちました。しかし、今では次のようにパラメーターを追加できます。
Java
Kotlin
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@PreAuthorize("hasAuthority('SCOPE_{scope}')")
public @interface HasScope {
String scope();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@PreAuthorize("hasAuthority('SCOPE_{scope}')")
annotation class HasScope (val scope:String)
次のようなことが可能になります。
Java
Kotlin
@HasScope("message:read")
public String method() { ... }
@HasScope("message:read")
fun method(): String { ... }
さらにいくつかの場所に SpEL 式を適用します。
安全な戻り値 - #14596 [GitHub] (英語) , #14597 [GitHub] (英語)
Spring Security の初期の頃から、Spring Bean に @PreAuthorize
と @PostAuthorize
のアノテーションを付けることができました。しかし、コントローラー、サービス、リポジトリだけがセキュリティ保護の対象ではありません。たとえば、管理者だけが Order#getPayment
メソッドを呼び出せるようにするドメインオブジェクト Order
はどうでしょうか。
現在、6.3 では、これらのメソッドにもアノテーションを付けることができます [GitHub] (英語) 。まず、Spring Bean と同じように、getPayment
メソッドにアノテーションを付けます。
Java
Kotlin
public class Order {
@HasScope("payment:read")
Payment getPayment() { ... }
}
class Order {
@HasScope("payment:read")
fun getPayment(): Payment { ... }
}
Java
Kotlin
public interface OrderRepository implements CrudRepository<Order, String> {
@AuthorizeReturnObject
Optional<Order> findOrderById(String id);
}
interface OrderRepository : CrudRepository<Order, String> {
@AuthorizeReturnObject
fun findOrderById(id: String?): Optional<Order?>?
}
その時点で、Spring Security は Order
インスタンスをプロキシする [GitHub] (英語) ことによって、findOrderById
から返された Order
を保護します。
エラー処理 - #14598 [GitHub] (英語) , #14600 [GitHub] (英語) , #14601 [GitHub] (英語)
このリリースでは、最新の新しいメソッドセキュリティアノテーションを使用して、メソッドレベルで障害をインターセプトして処理する [GitHub] (英語) こともできます。
Java
Kotlin
public class Payment {
@HandleAuthorizationDenied(handlerClass=Mask.class)
@PreAuthorize("hasAuthority('card:read')")
public String getCreditCardNumber() { ... }
}
class Payment {
@HandleAuthorizationDenied(handlerClass=Mask.class)
@PreAuthorize("hasAuthority('card:read')")
fun getCreditCardNumber(): String { ... }
}
Mask
Bean を公開します:
Java
Kotlin
@Component
public class Mask implements MethodAuthorizationDeniedHandler {
@Override
public Object handleDeniedInvocation(MethodInvocation invocation, AuthorizationResult result) {
return "***";
}
}
@Component
class Mask : MethodAuthorizationDeniedHandler {
fun handleDeniedInvocation(invocation: MethodInvocation?, result: AuthorizationResult?): Any = "***"
}
そうすると、Payment#getCreditCardNumber
への不正な呼び出しは、番号の代わりに ***
を返します。
これらすべての機能が連携して動作する様子は、最新の Spring Security データサンプル [GitHub] (英語) で確認できます。
侵害されたパスワードのチェック - #7395 [GitHub] (英語)
ユーザーにパスワードを選択させる場合は、そのパスワードがすでに侵害されていないことを確認することが重要です。Spring Security 6.3 を使用すると、CompromisedPasswordChecker
Bean を公開するだけでこれが簡単になります。
Java
Kotlin
@Bean
public CompromisedPasswordChecker compromisedPasswordChecker() {
return new HaveIBeenPwnedRestApiPasswordChecker();
}
@Bean
fun compromisedPasswordChecker(): CompromisedPasswordChecker = HaveIBeenPwnedRestApiPasswordChecker()
spring-security-rsa
は現在 Spring Security - #14202 [GitHub] (英語) の一部です
2017 年以来、Spring Security はさまざまな Spring Security 拡張機能を Spring Security 本体に組み込むという長期的な取り組みを進めてきました。6.3 では、spring-security-rsa
がこれらのプロジェクトの最新版となり、チームが長期的に維持し、機能を追加できます。
spring-security-rsa
は、KeyStore
を操作するためのよりシンプルな API [GitHub] (英語) と同様に、便利な BytesEncryptor
[GitHub] (英語) 実装 [GitHub] (英語) を多数提供します。
OAuth 2.0 トークン交換許可 - #5199 [GitHub] (英語)
Spring Security で最も投票数が多かった OAuth 2.0 機能 [GitHub] (英語) の 1 つが、6.3 に導入されました。これは、OAuth 2.0 トークン交換許可 [IETF] (英語) のサポートです。
トークン交換用に設定されたクライアントの場合は、次のように TokenExchangeAuthorizedClientProvider
インスタンスを OAuth2AuthorizedClientManager
に追加することで、Spring Security でアクティブ化できます。
Java
Kotlin
@Bean
public OAuth2AuthorizedClientProvider tokenExchange() {
return new TokenExchangeOAuth2AuthorizedClientProvider();
}
@Bean
fun tokenExchange(): OAuth2AuthorizedClientProvider = TokenExchangeOAuth2AuthorizedClientProvider()
その後、通常どおり @RegisteredOAuth2AuthorizedClient
アノテーションを使用して、リソースサーバーに必要な拡張された権限を持つ適切なトークンを取得します。
その他のハイライト
gh-14655 [GitHub] (英語) -
DelegatingAuthenticationConverter
を追加gh-6192 [GitHub] (英語) - WebFlux に同時セッション制御を追加する ( ドキュメント )
gh-14193 [GitHub] (英語) - CAS ゲートウェイ認証のサポートを追加しました
gh-13259 [GitHub] (英語) - UserInfo が呼び出されるタイミングをカスタマイズする
gh-14168 [GitHub] (英語) - OAuth2AuthorizationRequestRedirectFilter にカスタマイズ可能な AuthorizationFailureHandler を導入
gh-14672 [GitHub] (英語) - OidcUserRequest と OidcUserInfo から OidcUser のマッピングをカスタマイズする
gh-13763 [GitHub] (英語) - リアクティブ OAuth2 クライアントコンポーネントモデルの構成を簡素化
gh-14758 [GitHub] (英語) - リアクティブ OAuth2 ドキュメントのランディングページを例とともに更新 ( ドキュメント )
gh-10538 [GitHub] (英語) - 証明書にバインドされた JWT アクセストークン検証をサポート
gh-14265 [GitHub] (英語) - UserInfo レスポンスでネストされたユーザー名をサポート
gh-14449 [GitHub] (英語) -
SecurityContext
引数リゾルバーを追加gh-11440 [GitHub] (英語) -
application/x-www-form-urlencoded
エンコードクライアント ID とシークレットの無効化を簡素化 ( サーブレットドキュメント、リアクティブドキュメント )
完全なリストについては、6.3.0-RC1 [GitHub] (英語) 、6.3.0-M3 [GitHub] (英語) 、6.3.0-M2 [GitHub] (英語) 、6.3.0-M1 [GitHub] (英語) のリリースノートを参照してください。