Skip to content

Commit 232c1d9

Browse files
committed
Add AssertionValidator
- Ships with support for customizing the OpenSAML validators to use - Or, you can supply your own instance of SAML20AssertionValidator Closes spring-projectsgh-15578
1 parent 2be012c commit 232c1d9

File tree

2 files changed

+415
-87
lines changed

2 files changed

+415
-87
lines changed

docs/modules/ROOT/pages/servlet/saml2/login/authentication.adoc

+110
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,60 @@ open class SecurityConfig {
192192
----
193193
======
194194

195+
If you are using xref:servlet/saml2/opensaml.adoc[OpenSAML 5], then we have a simpler way, using `OpenSaml5AuthenticationProvider.AssertionValidator`:
196+
197+
[tabs]
198+
======
199+
Java::
200+
+
201+
[source,java,role="primary"]
202+
----
203+
@Configuration
204+
@EnableWebSecurity
205+
public class SecurityConfig {
206+
207+
@Bean
208+
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
209+
OpenSaml5AuthenticationProvider authenticationProvider = new OpenSaml5AuthenticationProvider();
210+
AssertionValidator assertionValidator = AssertionValidator.builder().clockSkew(Duration.ofMinutes(10)).build();
211+
authenticationProvider.setAssertionValidator(assertionValidator);
212+
http
213+
.authorizeHttpRequests(authz -> authz
214+
.anyRequest().authenticated()
215+
)
216+
.saml2Login(saml2 -> saml2
217+
.authenticationManager(new ProviderManager(authenticationProvider))
218+
);
219+
return http.build();
220+
}
221+
}
222+
----
223+
224+
Kotlin::
225+
+
226+
[source,kotlin,role="secondary"]
227+
----
228+
229+
230+
@Configuration @EnableWebSecurity
231+
class SecurityConfig {
232+
@Bean
233+
@Throws(Exception::class)
234+
fun filterChain(http: HttpSecurity): SecurityFilterChain {
235+
val authenticationProvider = OpenSaml5AuthenticationProvider()
236+
val assertionValidator = AssertionValidator.builder().clockSkew(Duration.ofMinutes(10)).build()
237+
authenticationProvider.setAssertionValidator(assertionValidator)
238+
http
239+
.authorizeHttpRequests{authz -> authz
240+
.anyRequest().authenticated()}
241+
.saml2Login{saml2 -> saml2
242+
.authenticationManager(ProviderManager(authenticationProvider))}
243+
return http.build()
244+
}
245+
}
246+
----
247+
======
248+
195249
[[servlet-saml2login-opensamlauthenticationprovider-userdetailsservice]]
196250
== Coordinating with a `UserDetailsService`
197251

@@ -368,6 +422,62 @@ provider.setAssertionValidator { assertionToken ->
368422
While recommended, it's not necessary to call ``OpenSaml4AuthenticationProvider``'s default assertion validator.
369423
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.
370424

425+
If you are using xref:servlet/saml2/opensaml.adoc[OpenSAML 5], then we have a simpler way using `OpenSaml5AuthenticationProvider.AssertionValidator`:
426+
427+
[tabs]
428+
======
429+
Java::
430+
+
431+
[source,java,role="primary"]
432+
----
433+
OpenSaml5AuthenticationProvider provider = new OpenSaml5AuthenticationProvider();
434+
OneTimeUseConditionValidator validator = ...;
435+
AssertionValidator assertionValidator = AssertionValidator.builder()
436+
.conditionValidators((c) -> c.add(validator)).build();
437+
provider.setAssertionValidator(assertionValidator);
438+
----
439+
440+
Kotlin::
441+
+
442+
[source,kotlin,role="secondary"]
443+
----
444+
val provider = OpenSaml5AuthenticationProvider()
445+
val validator: OneTimeUseConditionValidator = ...;
446+
val assertionValidator = AssertionValidator.builder()
447+
.conditionValidators { add(validator) }.build()
448+
provider.setAssertionValidator(assertionValidator)
449+
----
450+
======
451+
452+
You can use this same builder to remove validators that you don't want to use like so:
453+
454+
[tabs]
455+
======
456+
Java::
457+
+
458+
[source,java,role="primary"]
459+
----
460+
OpenSaml5AuthenticationProvider provider = new OpenSaml5AuthenticationProvider();
461+
AssertionValidator assertionValidator = AssertionValidator.builder()
462+
.conditionValidators((c) -> c.removeIf(AudienceRestrictionValidator.class::isInstance)).build();
463+
provider.setAssertionValidator(assertionValidator);
464+
----
465+
466+
Kotlin::
467+
+
468+
[source,kotlin,role="secondary"]
469+
----
470+
val provider = new OpenSaml5AuthenticationProvider()
471+
val assertionValidator = AssertionValidator.builder()
472+
.conditionValidators {
473+
c: List<ConditionValidator> -> c.removeIf { it is AudienceRestrictionValidator }
474+
}.build()
475+
provider.setAssertionValidator(assertionValidator)
476+
----
477+
======
478+
479+
The way this reads is: Remove all the default validators and only add `AudienceRestrictionValidator` back in.
480+
371481
[[servlet-saml2login-opensamlauthenticationprovider-decryption]]
372482
== Customizing Decryption
373483

0 commit comments

Comments
 (0)