Skip to content

Commit 9731386

Browse files
committed
Correctly set "Destination" in AuthNRequest message
Fixes gh-7494 #7494
1 parent 69eacac commit 9731386

File tree

2 files changed

+58
-21
lines changed

2 files changed

+58
-21
lines changed

saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/servlet/filter/Saml2WebSsoAuthenticationRequestFilter.java

+1-6
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,7 @@ private Saml2AuthenticationRequest createAuthenticationRequest(RelyingPartyRegis
107107
String localSpEntityId = Saml2Utils.getServiceProviderEntityId(relyingParty, request);
108108
return new Saml2AuthenticationRequest(
109109
localSpEntityId,
110-
Saml2Utils.resolveUrlTemplate(
111-
relyingParty.getAssertionConsumerServiceUrlTemplate(),
112-
Saml2Utils.getApplicationUri(request),
113-
relyingParty.getRemoteIdpEntityId(),
114-
relyingParty.getRegistrationId()
115-
),
110+
relyingParty.getIdpWebSsoUrl(),
116111
relyingParty.getSigningCredentials()
117112
);
118113
}

samples/boot/saml2login/src/integration-test/java/org/springframework/security/samples/Saml2LoginIntegrationTests.java

+57-15
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,10 @@
1515
*/
1616
package org.springframework.security.samples;
1717

18-
import org.springframework.beans.factory.annotation.Autowired;
19-
import org.springframework.boot.SpringBootConfiguration;
20-
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
21-
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
22-
import org.springframework.boot.test.context.SpringBootTest;
23-
import org.springframework.context.annotation.ComponentScan;
24-
import org.springframework.http.MediaType;
25-
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
26-
import org.springframework.test.context.junit4.SpringRunner;
27-
import org.springframework.test.util.AssertionErrors;
28-
import org.springframework.test.web.servlet.MockMvc;
29-
import org.springframework.test.web.servlet.ResultActions;
30-
import org.springframework.test.web.servlet.ResultMatcher;
31-
18+
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
19+
import net.shibboleth.utilities.java.support.xml.BasicParserPool;
3220
import net.shibboleth.utilities.java.support.xml.SerializeSupport;
21+
import net.shibboleth.utilities.java.support.xml.XMLParserException;
3322
import org.hamcrest.Matcher;
3423
import org.joda.time.DateTime;
3524
import org.junit.Test;
@@ -38,8 +27,10 @@
3827
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
3928
import org.opensaml.core.xml.io.MarshallerFactory;
4029
import org.opensaml.core.xml.io.MarshallingException;
30+
import org.opensaml.core.xml.io.UnmarshallingException;
4131
import org.opensaml.saml.common.SignableSAMLObject;
4232
import org.opensaml.saml.saml2.core.Assertion;
33+
import org.opensaml.saml.saml2.core.AuthnRequest;
4334
import org.opensaml.saml.saml2.core.EncryptedAssertion;
4435
import org.opensaml.saml.saml2.core.EncryptedID;
4536
import org.opensaml.saml.saml2.core.Response;
@@ -55,9 +46,26 @@
5546
import org.opensaml.xmlsec.signature.support.SignatureConstants;
5647
import org.opensaml.xmlsec.signature.support.SignatureException;
5748
import org.opensaml.xmlsec.signature.support.SignatureSupport;
49+
import org.springframework.beans.factory.annotation.Autowired;
50+
import org.springframework.boot.SpringBootConfiguration;
51+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
52+
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
53+
import org.springframework.boot.test.context.SpringBootTest;
54+
import org.springframework.context.annotation.ComponentScan;
55+
import org.springframework.http.MediaType;
56+
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
57+
import org.springframework.test.context.junit4.SpringRunner;
58+
import org.springframework.test.util.AssertionErrors;
59+
import org.springframework.test.web.servlet.MockMvc;
60+
import org.springframework.test.web.servlet.ResultActions;
61+
import org.springframework.test.web.servlet.ResultMatcher;
62+
import org.springframework.util.MultiValueMap;
63+
import org.springframework.web.util.UriComponentsBuilder;
64+
import org.w3c.dom.Document;
5865
import org.w3c.dom.Element;
5966

6067
import java.io.ByteArrayInputStream;
68+
import java.net.URLDecoder;
6169
import java.nio.charset.StandardCharsets;
6270
import java.security.KeyException;
6371
import java.security.PrivateKey;
@@ -78,6 +86,7 @@
7886
import static org.springframework.security.samples.OpenSamlActionTestingSupport.buildSubjectConfirmation;
7987
import static org.springframework.security.samples.OpenSamlActionTestingSupport.buildSubjectConfirmationData;
8088
import static org.springframework.security.samples.OpenSamlActionTestingSupport.encryptNameId;
89+
import static org.springframework.security.samples.OpenSamlActionTestingSupport.inflate;
8190
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
8291
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;
8392
import static org.springframework.security.web.WebAttributes.AUTHENTICATION_EXCEPTION;
@@ -131,6 +140,29 @@ public void authenticateRequestWhenRelayStateThenRespondsWithRedirectAndEncodedR
131140
.andExpect(header().string("Location", containsString("RelayState=relay%20state%20value%20with%20spaces")));
132141
}
133142

143+
@Test
144+
public void authenticateRequestWhenWorkingThenDestinationAttributeIsSet() throws Exception {
145+
final String redirectedUrl = mockMvc.perform(get("http://localhost:8080/saml2/authenticate/simplesamlphp"))
146+
.andExpect(status().is3xxRedirection())
147+
.andReturn()
148+
.getResponse()
149+
.getRedirectedUrl();
150+
MultiValueMap<String, String> parameters =
151+
UriComponentsBuilder.fromUriString(redirectedUrl).build(true).getQueryParams();
152+
String request = parameters.getFirst("SAMLRequest");
153+
AssertionErrors.assertNotNull("SAMLRequest parameter is missing", request);
154+
request = URLDecoder.decode(request);
155+
request = inflate(OpenSamlActionTestingSupport.decode(request));
156+
AuthnRequest authnRequest = (AuthnRequest) fromXml(request);
157+
String destination = authnRequest.getDestination();
158+
assertEquals(
159+
"Destination must match",
160+
"https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php",
161+
destination
162+
);
163+
}
164+
165+
134166
@Test
135167
public void authenticateWhenResponseIsSignedThenItSucceeds() throws Exception {
136168
Assertion assertion = buildAssertion(USERNAME);
@@ -248,7 +280,7 @@ public void authenticateWhenIssuerIsInvalidThenItFails() throws Exception {
248280
"invalid_issuer",
249281
containsString(
250282
"Response issuer 'invalid issuer' doesn't match "+
251-
"'https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php'"
283+
"'https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php'"
252284
)
253285
)
254286
);
@@ -330,6 +362,16 @@ private String toXml(XMLObject object) throws MarshallingException {
330362
return SerializeSupport.nodeToString(element);
331363
}
332364

365+
private XMLObject fromXml(String xml)
366+
throws XMLParserException, UnmarshallingException, ComponentInitializationException {
367+
BasicParserPool parserPool = new BasicParserPool();
368+
parserPool.initialize();
369+
Document document = parserPool.parse(new ByteArrayInputStream(xml.getBytes(UTF_8)));
370+
Element element = document.getDocumentElement();
371+
return XMLObjectProviderRegistrySupport.getUnmarshallerFactory().getUnmarshaller(element).unmarshall(element);
372+
373+
}
374+
333375
private X509Certificate decodeCertificate(String source) {
334376
try {
335377
final CertificateFactory factory = CertificateFactory.getInstance("X.509");

0 commit comments

Comments
 (0)