Correctly set "Destination" in AuthNRequest message
Fixes gh-7494 https://github.com/spring-projects/spring-security/issues/7494
This commit is contained in:
parent
69eacac514
commit
9731386de5
|
@ -107,12 +107,7 @@ public class Saml2WebSsoAuthenticationRequestFilter extends OncePerRequestFilter
|
|||
String localSpEntityId = Saml2Utils.getServiceProviderEntityId(relyingParty, request);
|
||||
return new Saml2AuthenticationRequest(
|
||||
localSpEntityId,
|
||||
Saml2Utils.resolveUrlTemplate(
|
||||
relyingParty.getAssertionConsumerServiceUrlTemplate(),
|
||||
Saml2Utils.getApplicationUri(request),
|
||||
relyingParty.getRemoteIdpEntityId(),
|
||||
relyingParty.getRegistrationId()
|
||||
),
|
||||
relyingParty.getIdpWebSsoUrl(),
|
||||
relyingParty.getSigningCredentials()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,21 +15,10 @@
|
|||
*/
|
||||
package org.springframework.security.samples;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.util.AssertionErrors;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.ResultMatcher;
|
||||
|
||||
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
|
||||
import net.shibboleth.utilities.java.support.xml.BasicParserPool;
|
||||
import net.shibboleth.utilities.java.support.xml.SerializeSupport;
|
||||
import net.shibboleth.utilities.java.support.xml.XMLParserException;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Test;
|
||||
|
@ -38,8 +27,10 @@ import org.opensaml.core.xml.XMLObject;
|
|||
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
|
||||
import org.opensaml.core.xml.io.MarshallerFactory;
|
||||
import org.opensaml.core.xml.io.MarshallingException;
|
||||
import org.opensaml.core.xml.io.UnmarshallingException;
|
||||
import org.opensaml.saml.common.SignableSAMLObject;
|
||||
import org.opensaml.saml.saml2.core.Assertion;
|
||||
import org.opensaml.saml.saml2.core.AuthnRequest;
|
||||
import org.opensaml.saml.saml2.core.EncryptedAssertion;
|
||||
import org.opensaml.saml.saml2.core.EncryptedID;
|
||||
import org.opensaml.saml.saml2.core.Response;
|
||||
|
@ -55,9 +46,26 @@ import org.opensaml.xmlsec.SignatureSigningParameters;
|
|||
import org.opensaml.xmlsec.signature.support.SignatureConstants;
|
||||
import org.opensaml.xmlsec.signature.support.SignatureException;
|
||||
import org.opensaml.xmlsec.signature.support.SignatureSupport;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.util.AssertionErrors;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.ResultMatcher;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyException;
|
||||
import java.security.PrivateKey;
|
||||
|
@ -78,6 +86,7 @@ import static org.springframework.security.samples.OpenSamlActionTestingSupport.
|
|||
import static org.springframework.security.samples.OpenSamlActionTestingSupport.buildSubjectConfirmation;
|
||||
import static org.springframework.security.samples.OpenSamlActionTestingSupport.buildSubjectConfirmationData;
|
||||
import static org.springframework.security.samples.OpenSamlActionTestingSupport.encryptNameId;
|
||||
import static org.springframework.security.samples.OpenSamlActionTestingSupport.inflate;
|
||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
|
||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;
|
||||
import static org.springframework.security.web.WebAttributes.AUTHENTICATION_EXCEPTION;
|
||||
|
@ -131,6 +140,29 @@ public class Saml2LoginIntegrationTests {
|
|||
.andExpect(header().string("Location", containsString("RelayState=relay%20state%20value%20with%20spaces")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateRequestWhenWorkingThenDestinationAttributeIsSet() throws Exception {
|
||||
final String redirectedUrl = mockMvc.perform(get("http://localhost:8080/saml2/authenticate/simplesamlphp"))
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getRedirectedUrl();
|
||||
MultiValueMap<String, String> parameters =
|
||||
UriComponentsBuilder.fromUriString(redirectedUrl).build(true).getQueryParams();
|
||||
String request = parameters.getFirst("SAMLRequest");
|
||||
AssertionErrors.assertNotNull("SAMLRequest parameter is missing", request);
|
||||
request = URLDecoder.decode(request);
|
||||
request = inflate(OpenSamlActionTestingSupport.decode(request));
|
||||
AuthnRequest authnRequest = (AuthnRequest) fromXml(request);
|
||||
String destination = authnRequest.getDestination();
|
||||
assertEquals(
|
||||
"Destination must match",
|
||||
"https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php",
|
||||
destination
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void authenticateWhenResponseIsSignedThenItSucceeds() throws Exception {
|
||||
Assertion assertion = buildAssertion(USERNAME);
|
||||
|
@ -248,7 +280,7 @@ public class Saml2LoginIntegrationTests {
|
|||
"invalid_issuer",
|
||||
containsString(
|
||||
"Response issuer 'invalid issuer' doesn't match "+
|
||||
"'https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php'"
|
||||
"'https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php'"
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -330,6 +362,16 @@ public class Saml2LoginIntegrationTests {
|
|||
return SerializeSupport.nodeToString(element);
|
||||
}
|
||||
|
||||
private XMLObject fromXml(String xml)
|
||||
throws XMLParserException, UnmarshallingException, ComponentInitializationException {
|
||||
BasicParserPool parserPool = new BasicParserPool();
|
||||
parserPool.initialize();
|
||||
Document document = parserPool.parse(new ByteArrayInputStream(xml.getBytes(UTF_8)));
|
||||
Element element = document.getDocumentElement();
|
||||
return XMLObjectProviderRegistrySupport.getUnmarshallerFactory().getUnmarshaller(element).unmarshall(element);
|
||||
|
||||
}
|
||||
|
||||
private X509Certificate decodeCertificate(String source) {
|
||||
try {
|
||||
final CertificateFactory factory = CertificateFactory.getInstance("X.509");
|
||||
|
|
Loading…
Reference in New Issue