Skip to content

Commit 91b0936

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 gh-15578
1 parent 2885b0f commit 91b0936

File tree

3 files changed

+450
-87
lines changed

3 files changed

+450
-87
lines changed

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

+112
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,64 @@ 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()
211+
.clockSkew(Duration.ofMinutes(10)).build();
212+
authenticationProvider.setAssertionValidator(assertionValidator);
213+
http
214+
.authorizeHttpRequests(authz -> authz
215+
.anyRequest().authenticated()
216+
)
217+
.saml2Login(saml2 -> saml2
218+
.authenticationManager(new ProviderManager(authenticationProvider))
219+
);
220+
return http.build();
221+
}
222+
}
223+
----
224+
225+
Kotlin::
226+
+
227+
[source,kotlin,role="secondary"]
228+
----
229+
230+
231+
@Configuration @EnableWebSecurity
232+
class SecurityConfig {
233+
@Bean
234+
@Throws(Exception::class)
235+
fun filterChain(http: HttpSecurity): SecurityFilterChain {
236+
val authenticationProvider = OpenSaml5AuthenticationProvider()
237+
val assertionValidator = AssertionValidator.builder().clockSkew(Duration.ofMinutes(10)).build()
238+
authenticationProvider.setAssertionValidator(assertionValidator)
239+
http {
240+
authorizeHttpRequests {
241+
authorize(anyRequest, authenticated)
242+
}
243+
saml2Login {
244+
authenticationManager = ProviderManager(authenticationProvider)
245+
}
246+
}
247+
return http.build()
248+
}
249+
}
250+
----
251+
======
252+
195253
[[servlet-saml2login-opensamlauthenticationprovider-userdetailsservice]]
196254
== Coordinating with a `UserDetailsService`
197255

@@ -368,6 +426,60 @@ provider.setAssertionValidator { assertionToken ->
368426
While recommended, it's not necessary to call ``OpenSaml4AuthenticationProvider``'s default assertion validator.
369427
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.
370428

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

0 commit comments

Comments
 (0)