@ -83,7 +83,7 @@ fun jwtDecoder(): JwtDecoder {
@@ -83,7 +83,7 @@ fun jwtDecoder(): JwtDecoder {
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`, `OpenSaml4AuthenticationTokenConverter`, and `OpenSaml5AuthenticationTokenConverter` will not process GET requests by default as of Spring Security 8.
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:
@ -114,7 +114,7 @@ fun authenticationConverter(val registrations: RelyingPartyRegistrationRepositor
@@ -114,7 +114,7 @@ fun authenticationConverter(val registrations: RelyingPartyRegistrationRepositor
----
======
If you must continue using `Saml2AuthenticationTokenConverter`, `OpenSaml4AuthenticationTokenConverter`, or `OpenSaml5AuthenticationTokenConverter` to process GET requests, you can call `setShouldConvertGetRequests` to `true.`
If you must continue using `Saml2AuthenticationTokenConverter` or `OpenSaml5AuthenticationTokenConverter` to process GET requests, you can call `setShouldConvertGetRequests` to `true.`
== Provide an AuthenticationConverter to BearerTokenAuthenticationFilter
To verify SAML 2.0 Responses, Spring Security uses xref:servlet/saml2/login/overview.adoc#servlet-saml2login-authentication-saml2authenticationtokenconverter[`Saml2AuthenticationTokenConverter`] to populate the `Authentication` request and xref:servlet/saml2/login/overview.adoc#servlet-saml2login-architecture[`OpenSaml4AuthenticationProvider`] to authenticate it.
To verify SAML 2.0 Responses, Spring Security uses xref:servlet/saml2/login/overview.adoc#servlet-saml2login-authentication-saml2authenticationtokenconverter[`Saml2AuthenticationTokenConverter`] to populate the `Authentication` request and xref:servlet/saml2/login/overview.adoc#servlet-saml2login-architecture[`OpenSaml5AuthenticationProvider`] to authenticate it.
You can configure this in a number of ways including:
@ -123,76 +123,7 @@ fun securityFilters(val http: HttpSecurity, val converter: AuthenticationConvert
@@ -123,76 +123,7 @@ fun securityFilters(val http: HttpSecurity, val converter: AuthenticationConvert
== Setting a Clock Skew
It's not uncommon for the asserting and relying parties to have system clocks that aren't perfectly synchronized.
For that reason, you can configure ``OpenSaml4AuthenticationProvider``'s default assertion validator with some tolerance:
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider();
If you are using xref:servlet/saml2/opensaml.adoc[OpenSAML 5], then we have a simpler way, using `OpenSaml5AuthenticationProvider.AssertionValidator`:
For that reason, you can configure `OpenSaml5AuthenticationProvider.AssertionValidator` as follows:
[tabs]
======
@ -381,86 +312,8 @@ open class MyUserDetailsResponseAuthenticationConverter(val delegate: ResponseAu
@@ -381,86 +312,8 @@ open class MyUserDetailsResponseAuthenticationConverter(val delegate: ResponseAu
If your `UserDetailsService` returns a value that also implements `AuthenticatedPrincipal`, then you don't need a custom authentication implementation.
====
Or, if you are using OpenSaml 4, then you can achieve something similar as follows:
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
UserDetailsService userDetailsService;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider();
<1> First, call the default converter, which extracts attributes and authorities from the response
<2> Second, call the xref:servlet/authentication/passwords/user-details-service.adoc#servlet-authentication-userdetailsservice[`UserDetailsService`] using the relevant information
<3> Third, return a custom authentication that includes the user details
[NOTE]
It's not required to call ``OpenSaml4AuthenticationProvider``'s default authentication converter.
It's not required to call ``OpenSaml5AuthenticationProvider``'s default authentication converter.
It returns a `Saml2AuthenticatedPrincipal` containing the attributes it extracted from ``AttributeStatement``s as well as the single `ROLE_USER` authority.
=== Configuring the Principal Name
@ -538,28 +391,10 @@ fun authenticationConverter(): ResponseAuthenticationConverter {
@@ -538,28 +391,10 @@ fun authenticationConverter(): ResponseAuthenticationConverter {
`OpenSaml4AuthenticationProvider` validates the `Issuer` and `Destination` values right after decrypting the `Response`.
`OpenSaml5AuthenticationProvider` validates the `Issuer` and `Destination` values right after decrypting the `Response`.
You can customize the validation by extending the default validator concatenating with your own response validator, or you can replace it entirely with yours.
For example, you can throw a custom exception with any additional information available in the `Response` object, like so:
[source,java]
----
OpenSaml4AuthenticationProvider provider = new OpenSaml4AuthenticationProvider();
throw new CustomSaml2AuthenticationException(result, inResponseTo);
}
return result;
});
----
When using `OpenSaml5AuthenticationProvider`, you can do the same with less boilerplate:
[source,java]
----
OpenSaml5AuthenticationProvider provider = new OpenSaml5AuthenticationProvider();
@ -583,74 +418,17 @@ OpenSAML performs `Asssertion#InResponseTo` validation in its `BearerSubjectConf
@@ -583,74 +418,17 @@ OpenSAML performs `Asssertion#InResponseTo` validation in its `BearerSubjectConf
====
== Performing Additional Assertion Validation
`OpenSaml4AuthenticationProvider` performs minimal validation on SAML 2.0 Assertions.
`OpenSaml5AuthenticationProvider` performs minimal validation on SAML 2.0 Assertions.
After verifying the signature, it will:
1. Validate `<AudienceRestriction>` and `<DelegationRestriction>` conditions
2. Validate ``<SubjectConfirmation>``s, expect for any IP address information
To perform additional validation, you can configure your own assertion validator that delegates to ``OpenSaml4AuthenticationProvider``'s default and then performs its own.
To perform additional validation, you can configure your own assertion validator that delegates to ``OpenSaml5AuthenticationProvider``'s default and then performs its own.
While recommended, it's not necessary to call ``OpenSaml4AuthenticationProvider``'s default assertion validator.
A circumstance where you would skip it would be if you don't need it to check the `<AudienceRestriction>` or the `<SubjectConfirmation>` since you are doing those yourself.
If you are using xref:servlet/saml2/opensaml.adoc[OpenSAML 5], then we have a simpler way using `OpenSaml5AuthenticationProvider.AssertionValidator`:
Spring Security decrypts `<saml2:EncryptedAssertion>`, `<saml2:EncryptedAttribute>`, and `<saml2:EncryptedID>` elements automatically by using the decryption xref:servlet/saml2/login/overview.adoc#servlet-saml2login-rpr-credentials[`Saml2X509Credential` instances] registered in the xref:servlet/saml2/login/overview.adoc#servlet-saml2login-relyingpartyregistration[`RelyingPartyRegistration`].
@ -49,7 +49,7 @@ This filter calls its configured `AuthenticationConverter` to create a `Saml2Aut
@@ -49,7 +49,7 @@ This filter calls its configured `AuthenticationConverter` to create a `Saml2Aut
This converter additionally resolves the <<servlet-saml2login-relyingpartyregistration, `RelyingPartyRegistration`>> and supplies it to `Saml2AuthenticationToken`.
image:{icondir}/number_2.png[] Next, the filter passes the token to its configured xref:servlet/authentication/architecture.adoc#servlet-authentication-providermanager[`AuthenticationManager`].
By default, it uses the <<servlet-saml2login-architecture,`OpenSaml4AuthenticationProvider`>>.
By default, it uses the <<servlet-saml2login-architecture,`OpenSaml5AuthenticationProvider`>>.
image:{icondir}/number_3.png[] If authentication fails, then _Failure_.
@ -43,7 +43,7 @@ This allows three valuable features:
@@ -43,7 +43,7 @@ This allows three valuable features:
* Implementations of `RelyingPartyRegistrationRepository` can more easily articulate a relationship between a relying party and its one or many corresponding asserting parties
* Implementations can verify metadata signatures
For example, `OpenSaml4AssertingPartyMetadataRepository` uses OpenSAML's `MetadataResolver`, and API whose implementations regularly refresh the underlying metadata in an expiry-aware fashion.
For example, `OpenSaml5AssertingPartyMetadataRepository` uses OpenSAML's `MetadataResolver`, and API whose implementations regularly refresh the underlying metadata in an expiry-aware fashion.
This means that you can now create a refreshable `RelyingPartyRegistrationRepository` in just a few lines of code:
@ -120,11 +120,11 @@ class RefreshableRelyingPartyRegistrationRepository : IterableRelyingPartyRegist
@@ -120,11 +120,11 @@ class RefreshableRelyingPartyRegistrationRepository : IterableRelyingPartyRegist
======
[TIP]
`OpenSaml4AssertingPartyMetadataRepository` also ships with a constructor so you can provide a custom `MetadataResolver`. Since the underlying `MetadataResolver` is doing the expiring and refreshing, if you use the constructor directly, you will only get these features by providing an implementation that does so.
`OpenSaml5AssertingPartyMetadataRepository` also ships with a constructor so you can provide a custom `MetadataResolver`. Since the underlying `MetadataResolver` is doing the expiring and refreshing, if you use the constructor directly, you will only get these features by providing an implementation that does so.
=== Verifying Metadata Signatures
You can also verify metadata signatures using `OpenSaml4AssertingPartyMetadataRepository` by providing the appropriate set of ``Saml2X509Credential``s as follows:
You can also verify metadata signatures using `OpenSaml5AssertingPartyMetadataRepository` by providing the appropriate set of ``Saml2X509Credential``s as follows: