SAML 2.0 遷移
當 <saml2:LogoutRequest> 驗證失敗時,預期 <saml2:LogoutResponse>
SAML 身份提供者要求服務提供者在無法處理 <saml2:LogoutRequest> 時返回一個錯誤 <saml2:LogoutResponse>。
Spring Security 的早期版本在某些情況下會返回 401 錯誤,這會中斷每個依賴方的登出請求和響應鏈。
在 Spring Security 7 中,此行為已修復,您無需執行任何操作。
但是,如果這給您帶來麻煩,您可以透過釋出一個 Saml2LogoutRequestResolver 來恢復舊行為,該解析器在需要錯誤 <saml2:LogoutRequest> 時返回 null。您可以像這樣建立一個委託
-
Java
-
Kotlin
@Bean
Saml2LogoutResponseResolver logoutResponseResolver(RelyingPartyRegistrationRepository registrations) {
OpenSaml5LogoutResponseResolver delegate = new OpenSaml5LogoutResponseResolver(registrations);
return new Saml2LogoutResponseResolver() {
@Override
public void resolve(HttpServletRequest request, Authentication authentication) {
delegate.resolve(request, authentication);
}
@Override
public void resolve(HttpServletRequest request, Authentication authentication, Saml2AuthenticationException error) {
return null;
}
};
}
@Bean
fun logoutResponseResolver(registrations: RelyingPartyRegistrationRepository?): Saml2LogoutResponseResolver {
val delegate = OpenSaml5LogoutResponseResolver(registrations)
return object : Saml2LogoutResponseResolver() {
override fun resolve(request: HttpServletRequest?, authentication: Authentication?) {
delegate.resolve(request, authentication)
}
override fun resolve(request: HttpServletRequest?, authentication: Authentication?, error: Saml2AuthenticationException?) {
return null
}
}
}
傾向於使用 Saml2ResponseAuthenticationAccessor 而不是 Saml2AuthenticatedPrincipal
Spring Security 7 將 <saml2:Assertion> 詳細資訊從主體中分離出來。這允許 Spring Security 檢索所需的斷言詳細資訊以執行單點登出。
這會棄用 Saml2AuthenticatedPrincipal。您不再需要實現它來使用 Saml2Authentication。
相反,憑據實現了 Saml2ResponseAssertionAccessor,Spring Security 7 在根據身份驗證確定適當操作時會優先使用它。
當使用預設值時,此更改會自動為您完成。
如果在升級時這給您帶來麻煩,您可以釋出一個自定義的 ResponseAuhenticationConverter 來返回 Saml2Authentication,而不是像這樣返回 Saml2AssertionAuthentication
-
Java
-
Kotlin
@Bean
OpenSaml5AuthenticationProvider authenticationProvider() {
OpenSaml5AuthenticationProvider authenticationProvider =
new OpenSaml5AuthenticationProvider();
ResponseAuthenticationConverter defaults = new ResponseAuthenticationConverter();
authenticationProvider.setResponseAuthenticationConverter(
defaults.andThen((authentication) -> new Saml2Authentication(
authentication.getPrincipal(),
authentication.getSaml2Response(),
authentication.getAuthorities())));
return authenticationProvider;
}
@Bean
fun authenticationProvider(): OpenSaml5AuthenticationProvider {
val authenticationProvider = OpenSaml5AuthenticationProvider()
val defaults = ResponseAuthenticationConverter()
authenticationProvider.setResponseAuthenticationConverter(
defaults.andThen { authentication ->
Saml2Authentication(authentication.getPrincipal(),
authentication.getSaml2Response(),
authentication.getAuthorities())
})
return authenticationProvider
}
如果您正在自行構造 Saml2Authentication 例項,請考慮更改為 Saml2AssertionAuthentication,以獲得與當前預設值相同的益處。
不要使用 Saml2AuthenticationTokenConverter 處理 <saml2:Response> GET 請求
Spring Security 不支援透過 GET 處理 <saml2:Response> 有效載荷,因為 SAML 2.0 規範不支援此操作。
為了更好地遵守這一點,從 Spring Security 8 開始,Saml2AuthenticationTokenConverter 和 OpenSaml5AuthenticationTokenConverter 預設將不處理 GET 請求。為了為此做準備,提供了屬性 shouldConvertGetRequests。要使用它,請像這樣釋出您自己的轉換器
-
Java
-
Kotlin
@Bean
OpenSaml5AuthenticationTokenConverter authenticationConverter(RelyingPartyRegistrationRepository registrations) {
OpenSaml5AuthenticationTokenConverter authenticationConverter = new OpenSaml5AuthenticationTokenConverter(registrations);
authenticationConverter.setShouldConvertGetRequests(false);
return authenticationConverter;
}
@Bean
fun authenticationConverter(val registrations: RelyingPartyRegistrationRepository): Saml2AuthenticationTokenConverter {
val authenticationConverter = Saml2AuthenticationTokenConverter(registrations)
authenticationConverter.setShouldConvertGetRequests(false)
return authenticationConverter
}
如果您必須繼續使用 Saml2AuthenticationTokenConverter 或 OpenSaml5AuthenticationTokenConverter 來處理 GET 請求,您可以將 setShouldConvertGetRequests 設定為 true。