Spring Security 6.3 新功能
Spring Security 6.3 提供許多新功能。以下是此版本的重點,或者您可以檢視發行說明,以取得每個功能和錯誤修復的詳細列表。
被動式 JDK 序列化支援
在支援 JDK 序列化的安全組件方面,Spring Security 歷史上一直相當積極,每個序列化版本僅支援一個 Spring Security 次要版本。這表示如果您有 JDK 序列化的安全組件,則在升級到下一個 Spring Security 版本之前,需要先撤離這些組件,因為它們將不再可反序列化。
現在 Spring Security 每六個月執行一次次要版本發布,這已成為一個更大的痛點。為了解決這個問題,Spring Security 現在將維持對 JDK 序列化的被動性,就像對 JSON 序列化一樣,從而實現更無縫的升級。
授權
最近幾個版本的持續主題一直是重構和改進 Spring Security 的授權子系統。從將 AccessDecisionManager
API 替換為 AuthorizationManager
開始,現在已經到了我們可以添加幾個令人興奮的新功能的階段。
註解參數 - #14480
-
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、#14597
自 Spring Security 早期以來,您就可以使用 @PreAuthorize
和 @PostAuthorize
註解 Spring bean。但是控制器、服務和儲存庫並不是您唯一關心安全性的東西。例如,如果有一個網域物件 Order
,只有管理員才能呼叫 Order#getPayment
方法呢?
現在在 6.3 中,您也可以註解這些方法。首先,像註解 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
實例來保護從 findOrderById
傳回的任何 Order
。
錯誤處理 - #14598、#14600、#14601
在此版本中,您還可以透過其最後一個新的方法安全註解,在方法層級攔截和處理失敗。
當您像這樣使用 @HandleAuthorizationDenied
註解方法時
-
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 Data 範例中看到所有這些功能一起運作。
洩漏密碼檢查 - #7395
如果您要讓使用者選擇密碼,那麼確保此密碼尚未洩漏至關重要。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
自 2017 年以來,Spring Security 一直在進行一項長期計畫,將各種 Spring Security 擴充功能整合到 Spring Security 本身中。在 6.3 中,spring-security-rsa
成為這些專案中的最新一個,這將有助於團隊長期維護並為其添加功能。
spring-security-rsa
提供了許多方便的 BytesEncryptor
實作,以及一個更簡單的 API 用於處理 KeyStore
s。
OAuth 2.0 令牌交換授權 - #5199
Spring Security 中最受歡迎的 OAuth 2.0 功能之一現在已在 6.3 中實作,即對OAuth 2.0 令牌交換授權的支援。
對於任何配置為令牌交換的用戶端,您可以透過將 TokenExchangeAuthorizedClientProvider
實例添加到您的 OAuth2AuthorizedClientManager
中,在 Spring Security 中啟動它,如下所示
-
Java
-
Kotlin
@Bean
public OAuth2AuthorizedClientProvider tokenExchange() {
return new TokenExchangeOAuth2AuthorizedClientProvider();
}
@Bean
fun tokenExchange(): OAuth2AuthorizedClientProvider = TokenExchangeOAuth2AuthorizedClientProvider()
然後像往常一樣使用 @RegisteredOAuth2AuthorizedClient
註解來檢索具有資源伺服器所需的擴展權限的適當令牌。
其他重點
-
gh-14655 - 新增
DelegatingAuthenticationConverter
-
gh-14193 - 新增對 CAS Gateway 身份驗證的支援
-
gh-13259 - 自訂何時呼叫 UserInfo
-
gh-14168 - 在 OAuth2AuthorizationRequestRedirectFilter 中引入可自訂的 AuthorizationFailureHandler
-
gh-14672 - 自訂從 OidcUserRequest 和 OidcUserInfo 映射 OidcUser
-
gh-13763 - 簡化反應式 OAuth2 用戶端組件模型的配置
-
gh-10538 - 支援憑證綁定的 JWT 存取令牌驗證
-
gh-14265 - 支援 UserInfo 回應中的巢狀使用者名稱
-
gh-14449 - 新增
SecurityContext
參數解析器 -
gh-11440 - 簡化停用 application/x-www-form-urlencoded 編碼用戶端 ID 和密碼 (servlet 文件, reactive 文件)