20
20
import java .time .Instant ;
21
21
import java .util .Collection ;
22
22
import java .util .Collections ;
23
+ import java .util .Map ;
23
24
import java .util .function .Consumer ;
24
25
25
26
import org .junit .jupiter .api .AfterEach ;
72
73
import org .springframework .security .web .util .matcher .AntPathRequestMatcher ;
73
74
import org .springframework .test .web .servlet .MockMvc ;
74
75
import org .springframework .test .web .servlet .MvcResult ;
76
+ import org .springframework .test .web .servlet .request .RequestPostProcessor ;
77
+ import org .springframework .web .util .UriComponentsBuilder ;
78
+ import org .springframework .web .util .UriUtils ;
75
79
76
80
import static org .assertj .core .api .Assertions .assertThat ;
77
81
import static org .hamcrest .Matchers .containsString ;
@@ -254,10 +258,9 @@ public void saml2LogoutRequestWhenDefaultsThenLogsOutAndSendsLogoutResponse() th
254
258
principal .setRelyingPartyRegistrationId ("get" );
255
259
Saml2Authentication user = new Saml2Authentication (principal , "response" ,
256
260
AuthorityUtils .createAuthorityList ("ROLE_USER" ));
257
- MvcResult result = this .mvc
258
- .perform (get ("/logout/saml2/slo" ).param ("SAMLRequest" , this .apLogoutRequest )
259
- .param ("RelayState" , this .apLogoutRequestRelayState ).param ("SigAlg" , this .apLogoutRequestSigAlg )
260
- .param ("Signature" , this .apLogoutRequestSignature ).with (authentication (user )))
261
+ MvcResult result = this .mvc .perform (get ("/logout/saml2/slo" ).param ("SAMLRequest" , this .apLogoutRequest )
262
+ .param ("RelayState" , this .apLogoutRequestRelayState ).param ("SigAlg" , this .apLogoutRequestSigAlg )
263
+ .param ("Signature" , this .apLogoutRequestSignature ).with (samlQueryString ()).with (authentication (user )))
261
264
.andExpect (status ().isFound ()).andReturn ();
262
265
String location = result .getResponse ().getHeader ("Location" );
263
266
assertThat (location ).startsWith ("https://ap.example.org/logout/saml2/response" );
@@ -316,8 +319,8 @@ public void saml2LogoutResponseWhenDefaultsThenRedirects() throws Exception {
316
319
assertThat (this .logoutRequestRepository .loadLogoutRequest (this .request )).isNotNull ();
317
320
this .mvc .perform (get ("/logout/saml2/slo" ).session (((MockHttpSession ) this .request .getSession ()))
318
321
.param ("SAMLResponse" , this .apLogoutResponse ).param ("RelayState" , this .apLogoutResponseRelayState )
319
- .param ("SigAlg" , this .apLogoutResponseSigAlg ).param ("Signature" , this .apLogoutResponseSignature ))
320
- .andExpect (status ().isFound ()).andExpect (redirectedUrl ("/login?logout" ));
322
+ .param ("SigAlg" , this .apLogoutResponseSigAlg ).param ("Signature" , this .apLogoutResponseSignature )
323
+ .with ( samlQueryString ())). andExpect (status ().isFound ()).andExpect (redirectedUrl ("/login?logout" ));
321
324
verifyNoInteractions (getBean (LogoutHandler .class ));
322
325
assertThat (this .logoutRequestRepository .loadLogoutRequest (this .request )).isNull ();
323
326
}
@@ -334,8 +337,9 @@ public void saml2LogoutResponseWhenInvalidSamlResponseThen401() throws Exception
334
337
Saml2Utils .samlInflate (Saml2Utils .samlDecode (this .apLogoutResponse )).getBytes (StandardCharsets .UTF_8 ));
335
338
this .mvc .perform (post ("/logout/saml2/slo" ).session ((MockHttpSession ) this .request .getSession ())
336
339
.param ("SAMLResponse" , deflatedApLogoutResponse ).param ("RelayState" , this .rpLogoutRequestRelayState )
337
- .param ("SigAlg" , this .apLogoutRequestSigAlg ).param ("Signature" , this .apLogoutResponseSignature ))
338
- .andExpect (status ().reason (containsString ("invalid_signature" ))).andExpect (status ().isUnauthorized ());
340
+ .param ("SigAlg" , this .apLogoutRequestSigAlg ).param ("Signature" , this .apLogoutResponseSignature )
341
+ .with (samlQueryString ())).andExpect (status ().reason (containsString ("invalid_signature" )))
342
+ .andExpect (status ().isUnauthorized ());
339
343
verifyNoInteractions (getBean (LogoutHandler .class ));
340
344
}
341
345
@@ -398,6 +402,10 @@ private <T> T getBean(Class<T> clazz) {
398
402
return this .spring .getContext ().getBean (clazz );
399
403
}
400
404
405
+ private SamlQueryStringRequestPostProcessor samlQueryString () {
406
+ return new SamlQueryStringRequestPostProcessor ();
407
+ }
408
+
401
409
@ EnableWebSecurity
402
410
@ Import (Saml2LoginConfigBeans .class )
403
411
static class Saml2LogoutDefaultsConfig {
@@ -602,4 +610,19 @@ public <O> O postProcess(O object) {
602
610
603
611
}
604
612
613
+ static class SamlQueryStringRequestPostProcessor implements RequestPostProcessor {
614
+
615
+ @ Override
616
+ public MockHttpServletRequest postProcessRequest (MockHttpServletRequest request ) {
617
+ UriComponentsBuilder builder = UriComponentsBuilder .newInstance ();
618
+ for (Map .Entry <String , String []> entries : request .getParameterMap ().entrySet ()) {
619
+ builder .queryParam (entries .getKey (),
620
+ UriUtils .encode (entries .getValue ()[0 ], StandardCharsets .ISO_8859_1 ));
621
+ }
622
+ request .setQueryString (builder .build (true ).toUriString ().substring (1 ));
623
+ return request ;
624
+ }
625
+
626
+ }
627
+
605
628
}
0 commit comments