This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Security 6.5.3! |
SAML 2.0 Migrations
Expect <saml2:LogoutResponse>
When <saml2:LogoutRequest>
Validation Fails
SAML identity providers expect service providers to return an error <saml2:LogoutResponse>
if it fails to process the <saml2:LogoutRequest>
.
Past versions of Spring Security returned a 401 in some cases, breaking the chain of logout requests and responses from each relying party.
In Spring Security 7, this behavior is repaired, and you need do nothing.
However, if this gives you trouble, you can revert back to the old behavior by publishing a Saml2LogoutRequestResolver
that returns null
when an error <saml2:LogoutRequest>
is needed.
You can create a delegate like this one:
-
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
}
}
}
Favor Saml2ResponseAuthenticationAccessor
over Saml2AuthenticatedPrincipal
Spring Security 7 separates <saml2:Assertion>
details from the principal.
This allows Spring Security to retrieve needed assertion details to perform Single Logout.
This deprecates Saml2AuthenticatedPrincipal
.
You no longer need to implement it to use Saml2Authentication
.
Instead, the credential implements Saml2ResponseAssertionAccessor
, which Spring Security 7 favors when determining the appropriate action based on the authentication.
This change is made automatically for you when using the defaults.
If this causes you trouble when upgrading, you can publish a custom ResponseAuhenticationConverter
to return a Saml2Authentication
instead of returning a Saml2AssertionAuthentication
like so:
-
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
}
If you are constructing a Saml2Authentication
instance yourself, consider changing to Saml2AssertionAuthentication
to get the same benefit as the current default.
Do Not Process <saml2:Response>
GET Requests with Saml2AuthenticationTokenConverter
Spring Security does not support processing <saml2:Response>
payloads over GET as this is not supported by the SAML 2.0 spec.
To better comply with this, Saml2AuthenticationTokenConverter
and OpenSaml5AuthenticationTokenConverter
will not process GET requests by default as of Spring Security 8.
To prepare for this, the property shouldConvertGetRequests
is available.
To use it, publish your own converter like so:
-
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
}
If you must continue using Saml2AuthenticationTokenConverter
or OpenSaml5AuthenticationTokenConverter
to process GET requests, you can call setShouldConvertGetRequests
to true.