4343import org .springframework .security .saml2 .provider .service .registration .RelyingPartyRegistrationRepository ;
4444import org .springframework .security .saml2 .provider .service .registration .Saml2MessageBinding ;
4545import org .springframework .security .saml2 .provider .service .servlet .filter .Saml2WebSsoAuthenticationFilter ;
46+ import org .springframework .security .saml2 .provider .service .web .authentication .logout .Saml2LogoutRequestFilter ;
4647import org .springframework .security .web .FilterChainProxy ;
4748import org .springframework .security .web .SecurityFilterChain ;
4849
@@ -65,15 +66,15 @@ class Saml2RelyingPartyAutoConfigurationTests {
6566 @ Test
6667 void autoConfigurationShouldBeConditionalOnRelyingPartyRegistrationRepositoryClass () {
6768 this .contextRunner .withPropertyValues (getPropertyValues (false )).withClassLoader (new FilteredClassLoader (
68- "org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository" ))
69+ "org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository" ))
6970 .run ((context ) -> assertThat (context ).doesNotHaveBean (RelyingPartyRegistrationRepository .class ));
7071 }
7172
7273 @ Test
7374 @ Deprecated
7475 void autoConfigurationShouldBeConditionalOnRelyingPartyRegistrationRepositoryClassDeprecated () {
7576 this .contextRunner .withPropertyValues (getPropertyValues (true )).withClassLoader (new FilteredClassLoader (
76- "org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository" ))
77+ "org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository" ))
7778 .run ((context ) -> assertThat (context ).doesNotHaveBean (RelyingPartyRegistrationRepository .class ));
7879 }
7980
@@ -144,6 +145,17 @@ void relyingPartyRegistrationRepositoryBeanShouldBeCreatedWhenPropertiesPresentD
144145 assertThat (registration .getDecryptionX509Credentials ()).hasSize (1 );
145146 assertThat (registration .getAssertingPartyDetails ().getVerificationX509Credentials ()).isNotNull ();
146147 assertThat (registration .getEntityId ()).isEqualTo ("{baseUrl}/saml2/foo-entity-id" );
148+ assertThat (registration .getSingleLogoutServiceLocation ())
149+ .isEqualTo ("https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SLOService.php" );
150+ assertThat (registration .getSingleLogoutServiceResponseLocation ())
151+ .isEqualTo ("https://simplesaml-for-spring-saml.cfapps.io/" );
152+ assertThat (registration .getSingleLogoutServiceBinding ()).isEqualTo (Saml2MessageBinding .POST );
153+ assertThat (registration .getAssertingPartyDetails ().getSingleLogoutServiceLocation ())
154+ .isEqualTo ("https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SLOService.php" );
155+ assertThat (registration .getAssertingPartyDetails ().getSingleLogoutServiceResponseLocation ())
156+ .isEqualTo ("https://simplesaml-for-spring-saml.cfapps.io/" );
157+ assertThat (registration .getAssertingPartyDetails ().getSingleLogoutServiceBinding ())
158+ .isEqualTo (Saml2MessageBinding .POST );
147159 });
148160 }
149161
@@ -252,12 +264,12 @@ void autoconfigurationWhenMetadataUrlAndPropertyPresentShouldUseBindingFromPrope
252264 setupMockResponse (server , new ClassPathResource ("saml/idp-metadata" ));
253265 this .contextRunner .withPropertyValues (PREFIX + ".foo.assertingparty.metadata-uri=" + metadataUrl ,
254266 PREFIX + ".foo.assertingparty.singlesignon.binding=redirect" ).run ((context ) -> {
255- RelyingPartyRegistrationRepository repository = context
256- .getBean (RelyingPartyRegistrationRepository .class );
257- RelyingPartyRegistration registration = repository .findByRegistrationId ("foo" );
258- assertThat (registration .getAssertingPartyDetails ().getSingleSignOnServiceBinding ())
259- .isEqualTo (Saml2MessageBinding .REDIRECT );
260- });
267+ RelyingPartyRegistrationRepository repository = context
268+ .getBean (RelyingPartyRegistrationRepository .class );
269+ RelyingPartyRegistration registration = repository .findByRegistrationId ("foo" );
270+ assertThat (registration .getAssertingPartyDetails ().getSingleSignOnServiceBinding ())
271+ .isEqualTo (Saml2MessageBinding .REDIRECT );
272+ });
261273 }
262274 }
263275
@@ -270,12 +282,12 @@ void autoconfigurationWhenMetadataUrlAndPropertyPresentShouldUseBindingFromPrope
270282 setupMockResponse (server , new ClassPathResource ("saml/idp-metadata" ));
271283 this .contextRunner .withPropertyValues (PREFIX + ".foo.identityprovider.metadata-uri=" + metadataUrl ,
272284 PREFIX + ".foo.identityprovider.singlesignon.binding=redirect" ).run ((context ) -> {
273- RelyingPartyRegistrationRepository repository = context
274- .getBean (RelyingPartyRegistrationRepository .class );
275- RelyingPartyRegistration registration = repository .findByRegistrationId ("foo" );
276- assertThat (registration .getAssertingPartyDetails ().getSingleSignOnServiceBinding ())
277- .isEqualTo (Saml2MessageBinding .REDIRECT );
278- });
285+ RelyingPartyRegistrationRepository repository = context
286+ .getBean (RelyingPartyRegistrationRepository .class );
287+ RelyingPartyRegistration registration = repository .findByRegistrationId ("foo" );
288+ assertThat (registration .getAssertingPartyDetails ().getSingleSignOnServiceBinding ())
289+ .isEqualTo (Saml2MessageBinding .REDIRECT );
290+ });
279291 }
280292 }
281293
@@ -377,6 +389,12 @@ void samlLoginShouldShouldBeConditionalOnSecurityWebFilterClassDeprecated() {
377389 .run ((context ) -> assertThat (context ).doesNotHaveBean (SecurityFilterChain .class ));
378390 }
379391
392+ @ Test
393+ void samlLogoutShouldBeConfigured () {
394+ this .contextRunner .withPropertyValues (getPropertyValues (false ))
395+ .run ((context ) -> assertThat (hasFilter (context , Saml2LogoutRequestFilter .class )).isTrue ());
396+ }
397+
380398 private String [] getPropertyValuesWithoutSigningCredentials (boolean signRequests , boolean useDeprecated ) {
381399 String assertingParty = useDeprecated ? "identityprovider" : "assertingparty" ;
382400 return new String [] {
@@ -387,7 +405,7 @@ private String[] getPropertyValuesWithoutSigningCredentials(boolean signRequests
387405 PREFIX + ".foo." + assertingParty
388406 + ".entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php" ,
389407 PREFIX + ".foo." + assertingParty
390- + ".verification.credentials[0].certificate-location=classpath:saml/certificate-location" };
408+ + ".verification.credentials[0].certificate-location=classpath:saml/certificate-location" };
391409 }
392410
393411 private String [] getPropertyValuesWithoutSsoBinding (boolean useDeprecated ) {
@@ -399,7 +417,7 @@ private String[] getPropertyValuesWithoutSsoBinding(boolean useDeprecated) {
399417 PREFIX + ".foo." + assertingParty
400418 + ".entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php" ,
401419 PREFIX + ".foo." + assertingParty
402- + ".verification.credentials[0].certificate-location=classpath:saml/certificate-location" };
420+ + ".verification.credentials[0].certificate-location=classpath:saml/certificate-location" };
403421 }
404422
405423 private String [] getPropertyValues (boolean useDeprecated ) {
@@ -409,6 +427,9 @@ private String[] getPropertyValues(boolean useDeprecated) {
409427 PREFIX + ".foo.signing.credentials[0].certificate-location=classpath:saml/certificate-location" ,
410428 PREFIX + ".foo.decryption.credentials[0].private-key-location=classpath:saml/private-key-location" ,
411429 PREFIX + ".foo.decryption.credentials[0].certificate-location=classpath:saml/certificate-location" ,
430+ PREFIX + ".foo.singlelogout.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SLOService.php" ,
431+ PREFIX + ".foo.singlelogout.response-url=https://simplesaml-for-spring-saml.cfapps.io/" ,
432+ PREFIX + ".foo.singlelogout.binding=post" ,
412433 PREFIX + ".foo." + assertingParty
413434 + ".singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php" ,
414435 PREFIX + ".foo." + assertingParty + ".singlesignon.binding=post" ,
@@ -417,9 +438,12 @@ private String[] getPropertyValues(boolean useDeprecated) {
417438 + ".entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php" ,
418439 PREFIX + ".foo." + assertingParty
419440 + ".verification.credentials[0].certificate-location=classpath:saml/certificate-location" ,
441+ PREFIX + ".foo.asserting-party.singlelogout.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SLOService.php" ,
442+ PREFIX + ".foo.asserting-party.singlelogout.response-url=https://simplesaml-for-spring-saml.cfapps.io/" ,
443+ PREFIX + ".foo.asserting-party.singlelogout.binding=post" ,
420444 PREFIX + ".foo.entity-id={baseUrl}/saml2/foo-entity-id" ,
421445 PREFIX + ".foo.acs.location={baseUrl}/login/saml2/foo-entity-id" ,
422- PREFIX + ".foo.acs.binding=redirect" };
446+ PREFIX + ".foo.acs.binding=redirect" };
423447 }
424448
425449 private boolean hasFilter (AssertableWebApplicationContext context , Class <? extends Filter > filter ) {
0 commit comments