Spring Security 6.4 新特性
Spring Security 6.4 提供了許多新特性。以下是該版本的主要亮點,您也可以檢視版本說明以獲取每個特性和錯誤修復的詳細列表。
棄用通知
隨著我們接近 Spring Security 7,及時瞭解棄用情況非常重要。因此,本節指出了 6.4 版本中的棄用項。
-
方法安全 (Method Security) - 建議使用
AuthorizationManager#authorize
代替AuthorizationManager#check
,後者已被棄用。這主要是為了讓返回型別成為介面而不是具體類。如果您正在呼叫AuthorizationManager#check
,請改為呼叫AuthorizationManager#authorize
。與此相關,接受
AuthorizationDecision
引數的AuthorizationEventPublisher#publishEvent
方法已被棄用,建議使用接受AuthorizationResult
介面引數的同名方法。 -
方法安全 (Method Security) -
PrePostTemplateDefaults
已被棄用,建議使用更通用的AnnotationTemplateExpressionDefaults
,因為現在 `@AuthenticationPrincipal` 和 `@CurrentSecurityContext` 也支援元註解屬性。如果您正在構造PrePostTemplateDefaults
,請將其更改為AnnotationTemplateExpressionDefaults
。 -
OAuth 2.0 -
NimbusOpaqueTokenIntrospector
已被棄用,建議使用SpringOpaqueTokenIntrospector
,以移除 Spring Security OAuth 2.0 資源伺服器對oidc-oauth2-sdk
包的依賴。如果您正在構造NimbusOpaqueTokenIntrospector
,請將其替換為SpringOpaqueTokenIntrospector
的建構函式。 -
OAuth 2.0 -
DefaultAuthorizationCodeTokenResponseClient
、DefaultClientCredentialsTokenResponseClient
、DefaultJwtBearerTokenResponseClient
、DefaultPasswordTokenResponseClient
、DefaultRefreshTokenTokenResponseClient
和DefaultTokenExchangeTokenResponseClient
已被棄用,建議使用其RestClient
等效實現。與此相關,
JwtBearerGrantRequestEntityConverter
、OAuth2AuthorizationCodeGrantRequestEntityConverter
、OAuth2ClientCredentialsGrantRequestEntityConverter
、OAuth2PasswordGrantRequestEntityConverter
、OAuth2RefreshTokenGrantRequestEntityConverter
已被棄用,建議改為向上述令牌響應客戶端之一提供DefaultOAuth2TokenRequestParametersConverter
的例項。例如,如果您有以下配置
private static class MyCustomConverter extends AbstractOAuth2AuthorizationGrantRequestEntityConverter<OAuth2AuthorizationCodeGrantRequest> { @Override protected MultiValueMap<String, String> createParameters (OAuth2AuthorizationCodeGrantRequest request) { MultiValueMap<String, String> parameters = super.createParameters(request); parameters.add("custom", "value"); return parameters; } } @Bean OAuth2AccessTokenResponseClient authorizationCode() { DefaultAuthorizationCodeTokenResponseClient client = new DefaultAuthorizationCodeTokenResponseClient(); Converter<AuthorizationCodeGrantRequest, RequestEntity<?>> entityConverter = new OAuth2AuthorizationCodeGrantRequestEntityConverter(); entityConverter.setParametersConverter(new MyCustomConverter()); client.setRequestEntityConverter(entityConverter); return client; }
此配置已棄用,因為它使用了
DefaultAuthorizationCodeTokenResponseClient
和OAuth2AuthorizationCodeGrantRequestEntityConverter
。現在推薦的配置是private static class MyCustomConverter implements Converter<OAuth2AuthorizationCodeGrantRequest, Map<String, String>> { @Override public MultiValueMap<String, String> convert(OAuth2AuthorizeCodeGrantRequest request) { MultiValueMap<String, String> parameters = OAuth2AuthorizationCodeGrantRequest.defaultParameters(request); parameters.add("custom", "value"); return parameters; } } @Bean OAuth2AccessTokenResponseClient authorizationCode() { RestClientAuthorizationCodeTokenResponseClient client = new RestClientAuthorizationCodeTokenResponseClient(); client.setParametersConverter(new MyCustomConverter()); return client; }
-
SAML 2.0 - Spring Security SAML 2.0 服務提供者介面的未版本化 OpenSAML 實現已被棄用,建議使用版本化實現。例如,
OpenSamlAuthenticationTokenConverter
現在已被OpenSaml4AuthenticationTokenConverter
和OpenSaml5AuthenticationTokenConverter
替代。如果您正在構造這些已棄用版本之一,請將其替換為您正在使用的 OpenSAML 版本對應的實現。 -
SAML 2.0 - 關於
AssertingPartyDetails
的方法已被棄用,建議使用接受AssertingPartyMetadata
介面引數的等效方法。 -
LDAP -
DistinguishedName
的用法現已棄用,以與 Spring LDAP 的棄用保持一致。
通行金鑰
Spring Security 現在支援通行金鑰。
方法安全
-
所有方法安全註解現在都支援 Spring Framework 的 `@AliasFor`。
-
`@AuthenticationPrincipal` 和 `@CurrentSecurityContext` 現在支援註解模板。
這意味著您現在可以像這樣使用 Spring 的元註解支援
-
Java
-
Kotlin
@Target(TargetType.TYPE) @Retention(RetentionPolicy.RUNTIME) @AuthenticationPrincipal("claims['{claim}']") @interface CurrentUsername { String claim() default "sub"; } // ... @GetMapping public String method(@CurrentUsername("username") String username) { // ... }
annotation CurrentUsername(val claim: String = "sub") // ... @GetMapping fun method(@CurrentUsername("username") val username: String): String { // ... }
-
-
對齊 Security 註解搜尋與
AbstractFallbackMethodSecurityMetadataSource
的演算法進行了一些改進。這有助於從早期版本的 Spring Security 進行遷移。 -
Native 應用現在可以使用 `@AuthorizeReturnObject`。
-
Native 應用現在可以在 `@PreAuthorize` 和 `@PostAuthorize` 中引用 bean。
-
SecurityAnnotationScanners
提供了一個方便的 API,用於掃描 Security 註解以及將 Security 的選擇和模板特性新增到自定義註解中。
OAuth 2.0
-
oauth2Login()
現在接受將OAuth2AuthorizationRequestResolver
作為 `@Bean`。 -
ClientRegistrations
現在支援外部獲取的配置。 -
在響應式
oauth2Login()
中向 DSL 添加了loginPage()
。 -
OIDC Back-Channel 支援現在接受型別為
logout+jwt
的退出登入令牌。 -
RestClient
現在可以配置OAuth2ClientHttpRequestInterceptor
來訪問受保護的資源請求。 -
添加了基於
RestClient
的OAuth2AccessTokenResponseClient
實現,以便更一致地配置訪問令牌請求。要啟用
RestClient
支援,只需為每種授權型別釋出一個 bean,如下例所示-
Java
-
Kotlin
@Configuration public class SecurityConfig { @Bean public OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> authorizationCodeAccessTokenResponseClient() { return new RestClientAuthorizationCodeTokenResponseClient(); } @Bean public OAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> refreshTokenAccessTokenResponseClient() { return new RestClientRefreshTokenTokenResponseClient(); } @Bean public OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> clientCredentialsAccessTokenResponseClient() { return new RestClientClientCredentialsTokenResponseClient(); } @Bean public OAuth2AccessTokenResponseClient<JwtBearerGrantRequest> jwtBearerAccessTokenResponseClient() { return new RestClientJwtBearerTokenResponseClient(); } @Bean public OAuth2AccessTokenResponseClient<TokenExchangeGrantRequest> tokenExchangeAccessTokenResponseClient() { return new RestClientTokenExchangeTokenResponseClient(); } }
@Configuration class SecurityConfig { @Bean fun authorizationCodeAccessTokenResponseClient(): OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> { return RestClientAuthorizationCodeTokenResponseClient() } @Bean fun refreshTokenAccessTokenResponseClient(): OAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> { return RestClientRefreshTokenTokenResponseClient() } @Bean fun clientCredentialsAccessTokenResponseClient(): OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> { return RestClientClientCredentialsTokenResponseClient() } @Bean fun jwtBearerAccessTokenResponseClient(): OAuth2AccessTokenResponseClient<JwtBearerGrantRequest> { return RestClientJwtBearerTokenResponseClient() } @Bean fun tokenExchangeAccessTokenResponseClient(): OAuth2AccessTokenResponseClient<TokenExchangeGrantRequest> { return RestClientTokenExchangeTokenResponseClient() } }
-
-
令牌交換現在支援重新整理令牌。
SAML 2.0
-
添加了OpenSAML 5 支援。現在您可以使用 OpenSAML 4 或 OpenSAML 5;預設情況下,Spring Security 將根據您 classpath 中存在的版本選擇正確的實現。
-
簡化了使用 EntityID 作為
registrationId
的過程。一種常見模式是透過其
entityID
來標識斷言方。在以前的版本中,這需要直接配置OpenSamlAuthenticationRequestResolver
。現在,請求解析器除了在路徑中查詢registrationId
外,預設還將其作為請求引數查詢。這允許您使用RelyingPartyRegistrations
或OpenSaml4/5AssertingPartyMetadataRepository
,而無需修改registrationId
值或自定義請求解析器。與此相關,您現在可以配置您的
authenticationRequestUri
包含一個查詢引數。 -
現在可以根據元資料的過期時間在後臺重新整理斷言方 (Asserting Parties)。
例如,您現在可以使用
OpenSaml5AssertingPartyMetadataRepository
來實現-
Java
-
Kotlin
@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(); } // ... }
@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() } // ... }
此實現還支援驗證元資料的簽名。
-
-
您現在可以簽署依賴方元資料。
-
RelyingPartyRegistrationRepository
的結果現在可以快取。如果您希望在應用啟動後延遲載入註冊值,這將非常有用。如果您希望透過 Spring Cache 控制何時重新整理元資料,這也很有用。 -
為了與 SAML 2.0 標準對齊,元資料端點現在使用
application/samlmetadata+xml
MIME 型別。
Web
-
CSRF BREACH 令牌現在更加一致。
-
“記住我” cookie 現在更加可定製。
-
安全過濾器鏈能發現更多無效配置。例如,在 `any-request` 過濾器鏈之後宣告的過濾器鏈是無效的,因為它永遠不會被呼叫。
-
Java
-
Kotlin
@Bean @Order(0) SecurityFilterChain api(HttpSecurity http) throws Exception { http // implicit securityMatcher("/**") .authorizeHttpRequests(...) .httpBasic(...) return http.build(); } @Bean @Order(1) SecurityFilterChain app(HttpSecurity http) throws Exception { http .securityMatcher("/app/**") .authorizeHttpRequests(...) .formLogin(...) return http.build(); }
@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() }
您可以在相關 ticket 中閱讀更多資訊。
-
-
ServerHttpSecurity
現在將ServerWebExchangeFirewall
作為一個 `@Bean` 拾取。
可觀測性
可觀測性現在支援分別開關授權、認證和請求的可觀測性。例如,要關閉過濾器鏈的可觀測性,您可以釋出一個如下所示的 `@Bean`。
-
Java
-
Kotlin
@Bean
SecurityObservationSettings allSpringSecurityObservations() {
return SecurityObservationSettings.withDefaults()
.shouldObserveFilterChains(false).build();
}
@Bean
fun allSpringSecurityObservations(): SecurityObservationSettings {
return SecurityObservationSettings.builder()
.shouldObserveFilterChains(false).build()
}
Kotlin
-
Kotlin DSL 現在支援 SAML 2.0 以及
GrantedAuthorityDefaults
和RoleHierarchy
的 `@Bean`。 -
`@PreFilter` 和 `@PostFilter` 現在在 Kotlin 中得到支援。
-
Kotlin 響應式 DSL 現在支援
SecurityContextRepository
。
ACL
-
AclAuthorizationStrategyImpl
現在支援RoleHierarchy
。