Revert "Correct signature handling for SAML2 AuthNRequest"

This reverts commit a3e09fadd7.
Build failure on Java 9+

XML generation does not add linefeeds by default
Change since Java 8
This commit is contained in:
Filip Hanik
2020-02-12 13:18:11 -08:00
parent ff8002eb2e
commit 43098d41cc
21 changed files with 243 additions and 1292 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,9 +14,12 @@
* limitations under the License.
*/
package org.springframework.security.saml2.provider.service.authentication;
package org.springframework.security.samples;
import org.springframework.security.saml2.Saml2Exception;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import org.apache.commons.codec.binary.Base64;
import org.apache.xml.security.algorithms.JCEMapper;
import org.apache.xml.security.encryption.XMLCipherParameters;
import org.joda.time.DateTime;
@@ -54,16 +57,23 @@ import org.opensaml.security.credential.CredentialSupport;
import org.opensaml.xmlsec.encryption.support.DataEncryptionParameters;
import org.opensaml.xmlsec.encryption.support.EncryptionException;
import org.opensaml.xmlsec.encryption.support.KeyEncryptionParameters;
import org.springframework.security.saml2.Saml2Exception;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.crypto.SecretKey;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.X509Certificate;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterOutputStream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.crypto.SecretKey;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Arrays.asList;
import static java.util.zip.Deflater.DEFLATED;
import static org.opensaml.security.crypto.KeySupport.generateKey;
/**
@@ -73,6 +83,8 @@ import static org.opensaml.security.crypto.KeySupport.generateKey;
*/
public class OpenSamlActionTestingSupport {
static Base64 UNCHUNKED_ENCODER = new Base64(0, new byte[] { '\n' });
/** ID used for all generated {@link Response} objects. */
final static String REQUEST_ID = "request";
@@ -82,6 +94,40 @@ public class OpenSamlActionTestingSupport {
/** ID used for all generated {@link Assertion} objects. */
final static String ASSERTION_ID = "assertion";
static String encode(byte[] b) {
return UNCHUNKED_ENCODER.encodeToString(b);
}
static byte[] decode(String s) {
return UNCHUNKED_ENCODER.decode(s);
}
static byte[] deflate(String s) {
try {
ByteArrayOutputStream b = new ByteArrayOutputStream();
DeflaterOutputStream deflater = new DeflaterOutputStream(b, new Deflater(DEFLATED, true));
deflater.write(s.getBytes(UTF_8));
deflater.finish();
return b.toByteArray();
}
catch (IOException e) {
throw new Saml2Exception("Unable to deflate string", e);
}
}
static String inflate(byte[] b) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
InflaterOutputStream iout = new InflaterOutputStream(out, new Inflater(true));
iout.write(b);
iout.finish();
return new String(out.toByteArray(), UTF_8);
}
catch (IOException e) {
throw new Saml2Exception("Unable to inflate string", e);
}
}
static EncryptedAssertion encryptAssertion(Assertion assertion, X509Certificate certificate) {
Encrypter encrypter = getEncrypter(certificate);
try {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.saml2.provider.service.authentication;
package org.springframework.security.samples;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.xml.BasicParserPool;
@@ -53,6 +52,7 @@ 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.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;
@@ -63,7 +63,6 @@ import org.springframework.web.util.UriComponentsBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayInputStream;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
@@ -74,18 +73,19 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.UUID;
import javax.servlet.http.HttpSession;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.matchesRegex;
import static org.hamcrest.Matchers.startsWith;
import static org.springframework.security.saml2.provider.service.authentication.OpenSamlActionTestingSupport.buildConditions;
import static org.springframework.security.saml2.provider.service.authentication.OpenSamlActionTestingSupport.buildIssuer;
import static org.springframework.security.saml2.provider.service.authentication.OpenSamlActionTestingSupport.buildSubject;
import static org.springframework.security.saml2.provider.service.authentication.OpenSamlActionTestingSupport.buildSubjectConfirmation;
import static org.springframework.security.saml2.provider.service.authentication.OpenSamlActionTestingSupport.buildSubjectConfirmationData;
import static org.springframework.security.saml2.provider.service.authentication.OpenSamlActionTestingSupport.encryptNameId;
import static org.springframework.security.samples.OpenSamlActionTestingSupport.buildConditions;
import static org.springframework.security.samples.OpenSamlActionTestingSupport.buildIssuer;
import static org.springframework.security.samples.OpenSamlActionTestingSupport.buildSubject;
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;
@@ -133,15 +133,10 @@ public class Saml2LoginIntegrationTests {
mockMvc.perform(
get("http://localhost:8080/saml2/authenticate/simplesamlphp")
.param("RelayState", "relay state value with spaces")
.param("OtherParam", "OtherParamValue")
.param("OtherParam2", "OtherParamValue2")
)
.andExpect(status().is3xxRedirection())
.andExpect(header().string("Location", startsWith("https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php?SAMLRequest=")))
.andExpect(header().string("Location", containsString("RelayState=relay%20state%20value%20with%20spaces")))
//check order of parameters
.andExpect(header().string("Location", matchesRegex(".*\\?SAMLRequest\\=.*\\&RelayState\\=.*\\&SigAlg\\=.*\\&Signature\\=.*")));
.andExpect(header().string("Location", containsString("RelayState=relay%20state%20value%20with%20spaces")));
}
@Test
@@ -156,7 +151,7 @@ public class Saml2LoginIntegrationTests {
String request = parameters.getFirst("SAMLRequest");
AssertionErrors.assertNotNull("SAMLRequest parameter is missing", request);
request = URLDecoder.decode(request);
request = Saml2Utils.samlInflate(Saml2Utils.samlDecode(request));
request = inflate(OpenSamlActionTestingSupport.decode(request));
AuthnRequest authnRequest = (AuthnRequest) fromXml(request);
String destination = authnRequest.getDestination();
assertEquals(
@@ -303,7 +298,7 @@ public class Saml2LoginIntegrationTests {
String xml = toXml(response);
return mockMvc.perform(post("http://localhost:8080/login/saml2/sso/simplesamlphp")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.param("SAMLResponse", Saml2Utils.samlEncode(xml.getBytes(UTF_8))))
.param("SAMLResponse", OpenSamlActionTestingSupport.encode(xml.getBytes(UTF_8))))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl(redirectUrl));
}