summaryrefslogtreecommitdiff
path: root/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2020-02-04 17:37:34 +0100
committerThomas Lenz <thomas.lenz@egiz.gv.at>2020-02-04 17:37:34 +0100
commite7610325ee2f1d1f4e97e1e7a9b212e692836b5a (patch)
treeed7c0dba5fed47e80e68b4ab5a63846c5724a8e7 /eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf
parent41ea2fdf782cd64d7d29f73c2e83f9c255810818 (diff)
downloadEAAF-Components-e7610325ee2f1d1f4e97e1e7a9b212e692836b5a.tar.gz
EAAF-Components-e7610325ee2f1d1f4e97e1e7a9b212e692836b5a.tar.bz2
EAAF-Components-e7610325ee2f1d1f4e97e1e7a9b212e692836b5a.zip
first stable version that uses OpenSAML 3.x
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf')
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java290
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java533
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/SoapBindingTest.java214
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataBuilderTest.java298
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataResolverTest.java725
5 files changed, 1901 insertions, 159 deletions
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java
index 6adce26e..87073e81 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java
@@ -3,6 +3,7 @@ package at.gv.egiz.eaaf.modules.pvp2.test.binding;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.Map;
@@ -13,23 +14,30 @@ import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiBuilderConfiguration;
import at.gv.egiz.eaaf.core.impl.idp.module.gui.DummyGuiBuilderConfigurationFactory;
import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
+import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory;
+import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface;
import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlMessageValidationException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare;
import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
+import at.gv.egiz.eaaf.modules.pvp2.test.metadata.MetadataResolverTest;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
+import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.opensaml.core.config.InitializationException;
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
import org.opensaml.core.xml.io.Unmarshaller;
import org.opensaml.core.xml.io.UnmarshallerFactory;
@@ -40,6 +48,7 @@ import org.opensaml.messaging.encoder.MessageEncodingException;
import org.opensaml.saml.common.SignableSAMLObject;
import org.opensaml.saml.saml2.core.RequestAbstractType;
import org.opensaml.saml.saml2.core.StatusResponseType;
+import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
@@ -49,9 +58,11 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
-import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.net.URIComparator;
import net.shibboleth.utilities.java.support.xml.XMLParserException;
+import okhttp3.HttpUrl;
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"/spring/test_eaaf_pvp.beans.xml"})
@@ -65,15 +76,27 @@ public class PostBindingTest {
@Autowired private PostBinding bindingImpl;
@Autowired private DummyCredentialProvider credentialProvider;
@Autowired private DummyGuiBuilderConfigurationFactory guiBuilderFactory;
+ @Autowired private PvpMetadataResolverFactory metadataResolverFactory;
+ @Autowired private IHttpClientFactory httpClientFactory;
+
+ private static MockWebServer mockWebServer;
+ private static HttpUrl mockServerUrl;
protected MockHttpServletRequest httpReq;
protected MockHttpServletResponse httpResp;
protected IRequest pendingReq;
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
@BeforeClass
- public static void classInitializer() throws InitializationException, ComponentInitializationException {
+ public static void classInitializer() throws Exception {
EaafOpenSaml3xInitializer.eaafInitialize();
+ mockWebServer = new MockWebServer();
+ mockServerUrl = mockWebServer.url("/sp/metadata");
}
/**
@@ -101,12 +124,14 @@ public class PostBindingTest {
}
@Test
- public void decodeRequestSuccess() throws MessageDecodingException, SecurityException, IOException, Pvp2Exception {
- final String serviceUrl = "http://testservice.org";
+ public void decodeRequestWrongEndpoint() throws MessageDecodingException, SecurityException,
+ IOException, Pvp2MetadataException {
+ final String serviceUrl = "https://wrongEndpoint/pvp2/post";
- final IPvp2MetadataProvider metadataProvider = null;
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_wrong_sig.xml", null, "jUnit metadata resolver", null);
- final boolean isSpEndPoint = false;
final URIComparator comparator = new EaafUriCompare(serviceUrl);
final String b64AuthnReq = Base64.getEncoder().encodeToString(IOUtils.toByteArray(
@@ -114,39 +139,169 @@ public class PostBindingTest {
httpReq.setMethod("POST");
httpReq.addParameter("SAMLRequest", b64AuthnReq);
+ try {
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator);
+ Assert.fail("Wrong http end-point not detected");
+
+ } catch (final Pvp2Exception e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.11", e.getErrorId());
+ Assert.assertNotNull("Parameters null", e.getParams());
+ Assert.assertEquals("Wrong numer of parameters", 1, e.getParams().length);
+
+
+ }
+
+ }
+
+ @Test
+ public void decodeRequestMissingSignature() throws MessageDecodingException, SecurityException,
+ IOException, Pvp2MetadataException {
+ final String serviceUrl = "https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp2/post";
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_wrong_sig.xml", null, "jUnit metadata resolver", null);
+
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ final String b64AuthnReq = Base64.getEncoder().encodeToString(IOUtils.toByteArray(
+ PostBindingTest.class.getResourceAsStream("/data/AuthRequest_without_sig_1.xml")));
+ httpReq.setMethod("POST");
+ httpReq.addParameter("SAMLRequest", b64AuthnReq);
+
+ try {
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator);
+ Assert.fail("Missing signature not detected");
+
+ } catch (final Pvp2Exception e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.02", e.getErrorId());
+
+ }
+
+ }
+
+ @Test
+ public void decodeRequestWrongSignature() throws MessageDecodingException, SecurityException,
+ IOException, Pvp2Exception {
+ final String serviceUrl = "https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp2/post";
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_wrong_sig.xml", null, "jUnit metadata resolver", null);
+
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ final String b64AuthnReq = Base64.getEncoder().encodeToString(IOUtils.toByteArray(
+ PostBindingTest.class.getResourceAsStream("/data/AuthRequest_with_sig_1.xml")));
+ httpReq.setMethod("POST");
+ httpReq.addParameter("SAMLRequest", b64AuthnReq);
+
+ try {
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator);
+ Assert.fail("Invalid signature not detected");
+
+ } catch (final Pvp2Exception e) {
+ org.springframework.util.Assert.isInstanceOf(SamlSigningException.class, e, "Wrong Exception type");
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.10", e.getErrorId());
+ Assert.assertNotNull("No error params", e.getParams());
+ Assert.assertEquals("Wrong param size", 1, e.getParams().length);
+
+ }
+
+ }
+
+ @Test
+ public void decodeRequestMsgExpired() throws MessageDecodingException, SecurityException, IOException, Pvp2Exception {
+ final String serviceUrl = "https://eidas-test.bmi.gv.at/ms_connector/pvp/post";
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_moaid_test.xml", null, "jUnit metadata resolver", null);
+
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ final String b64AuthnReq = new String(IOUtils.toByteArray(
+ PostBindingTest.class.getResourceAsStream("/data/AuthRequest_withsig_expired.b64")), "UTF-8");
+ httpReq.setMethod("POST");
+ httpReq.addParameter("SAMLRequest", b64AuthnReq);
+
+
+ try {
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator);
+ Assert.fail("Expired msg not detected");
+
+ } catch (final Pvp2Exception e) {
+ org.springframework.util.Assert.isInstanceOf(SamlMessageValidationException.class, e, "Wrong Exception type");
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.11", e.getErrorId());
+ Assert.assertNotNull("No error params", e.getParams());
+ Assert.assertEquals("Wrong param size", 1, e.getParams().length);
+
+ }
+
+ }
+
+ @Test
+ public void decodeRequestSuccessMetadataReloadRequired() throws MessageDecodingException, SecurityException,
+ IOException, Pvp2Exception, CredentialsNotAvailableException, XMLParserException, UnmarshallingException {
+ final String serviceUrl = "http://testservice.org";
+
+ final String b64AuthnReq = generateSaml2AuthnRequest(
+ credentialProvider.getIdpMetaDataSigningCredential());
+ httpReq.setMethod("POST");
+ httpReq.addParameter("SAMLRequest", b64AuthnReq);
+
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(new String(IOUtils.toByteArray(
+ MetadataResolverTest.class.getResourceAsStream(
+ "/data/pvp_metadata_wrong_sig.xml")), "UTF-8"))
+ .setHeader("Content-Type", "text/xml"));
+
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(new String(IOUtils.toByteArray(
+ MetadataResolverTest.class.getResourceAsStream(
+ "/data/pvp_metadata_junit_keystore.xml")), "UTF-8"))
+ .setHeader("Content-Type", "text/xml"));
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ mockServerUrl.url().toString(),
+ null, "jUnit test", httpClientFactory.getHttpClient());
+
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
final InboundMessageInterface msg =
- bindingImpl.decode(httpReq, httpResp, metadataProvider, isSpEndPoint, comparator);
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator);
Assert.assertNotNull("PVP msg is null", msg);
- Assert.assertNull("RelayState is not null", msg.getRelayState());
+ Assert.assertNull("RelayState not null", msg.getRelayState());
Assert.assertNotNull("AuthnReq is null", msg.getInboundMessage());
Assert.assertNotNull("EntityId is null", msg.getEntityID());
Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg.getEntityID());
- Assert.assertFalse("Wrong isVerified flag", msg.isVerified());
+ Assert.assertTrue("Wrong isVerified flag", msg.isVerified());
}
@Test
- public void decodeRequestSuccessWithRelayState() throws MessageDecodingException, SecurityException,
- IOException, Pvp2Exception {
+ public void decodeRequestSuccessWithRelayStateRsaSig() throws MessageDecodingException, SecurityException,
+ IOException, Pvp2Exception, CredentialsNotAvailableException, XMLParserException, UnmarshallingException {
final String serviceUrl = "http://testservice.org";
final String relayState = RandomStringUtils.randomAlphanumeric(10);
- final String b64AuthnReq = Base64.getEncoder().encodeToString(IOUtils.toByteArray(
- PostBindingTest.class.getResourceAsStream("/data/AuthRequest_with_sig_1.xml")));
+ final String b64AuthnReq = generateSaml2AuthnRequest(
+ credentialProvider.getIdpMetaDataSigningCredential());
httpReq.setMethod("POST");
httpReq.addParameter("SAMLRequest", b64AuthnReq);
httpReq.addParameter("RelayState", relayState);
- final IPvp2MetadataProvider metadataProvider = null;
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null);
- final boolean isSpEndPoint = false;
final URIComparator comparator = new EaafUriCompare(serviceUrl);
-
final InboundMessageInterface msg =
- bindingImpl.decode(httpReq, httpResp, metadataProvider, isSpEndPoint, comparator);
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator);
Assert.assertNotNull("PVP msg is null", msg);
Assert.assertNotNull("RelayState is not null", msg.getRelayState());
@@ -154,64 +309,63 @@ public class PostBindingTest {
Assert.assertNotNull("AuthnReq is null", msg.getInboundMessage());
Assert.assertNotNull("EntityId is null", msg.getEntityID());
Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg.getEntityID());
- Assert.assertFalse("Wrong isVerified flag", msg.isVerified());
+ Assert.assertTrue("Wrong isVerified flag", msg.isVerified());
}
@Test
- public void decodeResponseSuccess() throws MessageDecodingException, SecurityException, IOException, Pvp2Exception {
+ public void decodeRequestSuccessWithoutRelayStateEcdsaSig() throws MessageDecodingException, SecurityException,
+ IOException, Pvp2Exception, CredentialsNotAvailableException, XMLParserException, UnmarshallingException {
final String serviceUrl = "http://testservice.org";
- final IPvp2MetadataProvider metadataProvider = null;
-
- final boolean isSpEndPoint = false;
- final URIComparator comparator = new EaafUriCompare(serviceUrl);
-
- final String b64AuthnReq = Base64.getEncoder().encodeToString(IOUtils.toByteArray(
- PostBindingTest.class.getResourceAsStream("/data/Response_with_sig_1.xml")));
+ final String b64AuthnReq = generateSaml2AuthnRequest(
+ credentialProvider.getIdpAssertionSigningCredential());
httpReq.setMethod("POST");
httpReq.addParameter("SAMLRequest", b64AuthnReq);
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null);
+
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
final InboundMessageInterface msg =
- bindingImpl.decode(httpReq, httpResp, metadataProvider, isSpEndPoint, comparator);
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator);
Assert.assertNotNull("PVP msg is null", msg);
Assert.assertNull("RelayState is not null", msg.getRelayState());
- Assert.assertNotNull("Response is null", msg.getInboundMessage());
+ Assert.assertNotNull("AuthnReq is null", msg.getInboundMessage());
Assert.assertNotNull("EntityId is null", msg.getEntityID());
- Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp/metadata", msg.getEntityID());
- Assert.assertFalse("Wrong isVerified flag", msg.isVerified());
+ Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg.getEntityID());
+ Assert.assertTrue("Wrong isVerified flag", msg.isVerified());
}
@Test
- public void decodeResponseSuccessWithRelayState() throws MessageDecodingException, SecurityException, IOException, Pvp2Exception {
+ public void decodeResponseSuccess() throws MessageDecodingException, SecurityException,
+ IOException, Pvp2Exception, CredentialsNotAvailableException, XMLParserException, UnmarshallingException {
final String serviceUrl = "http://testservice.org";
- final String relayState = RandomStringUtils.randomAlphanumeric(10);
- final String b64AuthnReq = Base64.getEncoder().encodeToString(IOUtils.toByteArray(
- PostBindingTest.class.getResourceAsStream("/data/Response_with_sig_1.xml")));
- httpReq.setMethod("POST");
- httpReq.addParameter("SAMLRequest", b64AuthnReq);
- httpReq.addParameter("RelayState", relayState);
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null);
- final IPvp2MetadataProvider metadataProvider = null;
-
- final boolean isSpEndPoint = false;
final URIComparator comparator = new EaafUriCompare(serviceUrl);
+ final String b64AuthnReq = generateSaml2Response(credentialProvider.getIdpMetaDataSigningCredential());
+ httpReq.setMethod("POST");
+ httpReq.addParameter("SAMLRequest", b64AuthnReq);
final InboundMessageInterface msg =
- bindingImpl.decode(httpReq, httpResp, metadataProvider, isSpEndPoint, comparator);
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator);
Assert.assertNotNull("PVP msg is null", msg);
- Assert.assertNotNull("RelayState is not null", msg.getRelayState());
- Assert.assertEquals("RelayState not match", relayState, msg.getRelayState());
+ Assert.assertNull("RelayState is not null", msg.getRelayState());
Assert.assertNotNull("Response is null", msg.getInboundMessage());
Assert.assertNotNull("EntityId is null", msg.getEntityID());
- Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp/metadata", msg.getEntityID());
- Assert.assertFalse("Wrong isVerified flag", msg.isVerified());
+ Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg.getEntityID());
+ Assert.assertTrue("Wrong isVerified flag", msg.isVerified());
}
@@ -445,4 +599,48 @@ public class PostBindingTest {
}
+ private String generateSaml2AuthnRequest(EaafX509Credential credentials)
+ throws XMLParserException, UnmarshallingException, Pvp2Exception, CredentialsNotAvailableException,
+ UnsupportedEncodingException {
+ final MockHttpServletRequest intHttpReq = new MockHttpServletRequest();
+ final MockHttpServletResponse intHttpResp = new MockHttpServletResponse();
+ guiBuilderFactory.setVelocityBuilderConfig(createDummyGuiConfig());
+ final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ PostBindingTest.class.getResourceAsStream("/data/AuthRequest_without_sig_1.xml"));
+ authnReq.setIssueInstant(DateTime.now());
+
+ bindingImpl.encodeRequest(intHttpReq, intHttpResp, authnReq, "http://testservice.org", null,
+ credentials, pendingReq);
+
+ Assert.assertEquals("http StatusCode", 200, intHttpResp.getStatus());
+ final String http = intHttpResp.getContentAsString();
+ Assert.assertNotNull("http body is null", http);
+ Assert.assertTrue("SAMLRequest parameter", http.contains(HTTP_FORM_SAMLREQ));
+ return extractParamFromHttpForm(http, HTTP_FORM_SAMLREQ);
+
+ }
+
+ private String generateSaml2Response(EaafX509Credential credentials)
+ throws XMLParserException, UnmarshallingException, Pvp2Exception, CredentialsNotAvailableException,
+ UnsupportedEncodingException {
+ final MockHttpServletRequest intHttpReq = new MockHttpServletRequest();
+ final MockHttpServletResponse intHttpResp = new MockHttpServletResponse();
+ guiBuilderFactory.setVelocityBuilderConfig(createDummyGuiConfig());
+ final StatusResponseType response = (StatusResponseType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ PostBindingTest.class.getResourceAsStream("/data/Response_without_sig_1.xml"));
+ response.setIssueInstant(DateTime.now());
+
+ bindingImpl.encodeResponse(intHttpReq, intHttpResp, response, "http://testservice.org", null,
+ credentials, pendingReq);
+
+ Assert.assertEquals("http StatusCode", 200, intHttpResp.getStatus());
+ final String http = intHttpResp.getContentAsString();
+ Assert.assertNotNull("http body is null", http);
+ Assert.assertTrue("SAMLRequest parameter", http.contains(HTTP_FORM_SAMLRESP));
+ return extractParamFromHttpForm(http, HTTP_FORM_SAMLRESP);
+
+ }
+
}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java
index a99c8461..23cc98a6 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java
@@ -6,15 +6,34 @@ import java.util.Base64;
import javax.xml.parsers.ParserConfigurationException;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
+import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory;
+import at.gv.egiz.eaaf.modules.pvp2.PvpConstants;
+import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
+import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlMessageValidationException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
+import at.gv.egiz.eaaf.modules.pvp2.test.metadata.MetadataResolverTest;
+
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
+import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.opensaml.core.config.InitializationException;
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
import org.opensaml.core.xml.io.UnmarshallingException;
import org.opensaml.core.xml.util.XMLObjectSupport;
@@ -22,6 +41,7 @@ import org.opensaml.messaging.decoder.MessageDecodingException;
import org.opensaml.messaging.encoder.MessageEncodingException;
import org.opensaml.saml.saml2.core.RequestAbstractType;
import org.opensaml.saml.saml2.core.StatusResponseType;
+import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
@@ -30,46 +50,57 @@ import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.xml.sax.SAXException;
-import at.gv.egiz.eaaf.core.api.IRequest;
-import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
-import at.gv.egiz.eaaf.modules.pvp2.PvpConstants;
-import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface;
-import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
-import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
-import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
-import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding;
-import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
-import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
-import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare;
-import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
-import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.net.URIComparator;
+import net.shibboleth.utilities.java.support.net.URISupport;
import net.shibboleth.utilities.java.support.xml.XMLParserException;
+import okhttp3.HttpUrl;
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration({"/spring/test_eaaf_pvp.beans.xml"})
-@TestPropertySource(locations = {"/config/config_1.props"})
+@ContextConfiguration({ "/spring/test_eaaf_pvp.beans.xml" })
+@TestPropertySource(locations = { "/config/config_1.props" })
public class RedirectBindingTest {
- public static final String HTTP_FORM_RELAYSTATE = "RelayState=";
- public static final String HTTP_FORM_SAMLREQ = "SAMLRequest=";
- public static final String HTTP_FORM_SAMLRESP = "SAMLResponse=";
+ public static final String HTTP_FORM_RELAYSTATE = "RelayState";
+ public static final String HTTP_FORM_RELAYSTATE_PARAM = HTTP_FORM_RELAYSTATE + "=";
+
+ public static final String HTTP_FORM_SAMLREQ = "SAMLRequest";
+ public static final String HTTP_FORM_SAMLREQ_PARAM = HTTP_FORM_SAMLREQ + "=";
+ public static final String HTTP_FORM_SAMLRESP = "SAMLResponse";
+ public static final String HTTP_FORM_SAMLRESP_PARM = HTTP_FORM_SAMLRESP + "=";
+
+ public static final String HTTP_REDIRECT_SIGALG = "SigAlg";
+ public static final String HTTP_REDIRECT_SIGALG_PARAM = HTTP_REDIRECT_SIGALG + "=";
+ public static final String HTTP_REDIRECT_SIGNATURE = "Signature";
+ public static final String HTTP_REDIRECT_SIGNATURE_PARAM = HTTP_REDIRECT_SIGNATURE + "=";
- public static final String HTTP_REDIRECT_SIGALG = "SigAlg=";
- public static final String HTTP_REDIRECT_SIGNATURE = "Signature=";
+ @Autowired
+ private RedirectBinding bindingImpl;
+ @Autowired
+ private DummyCredentialProvider credentialProvider;
+ @Autowired
+ private PvpMetadataResolverFactory metadataResolverFactory;
+ @Autowired private IHttpClientFactory httpClientFactory;
- @Autowired private RedirectBinding bindingImpl;
- @Autowired private DummyCredentialProvider credentialProvider;
- @Autowired private PvpMetadataResolverFactory metadataResolverFactory;
+ private static MockWebServer mockWebServer;
+ private static HttpUrl mockServerUrl;
protected MockHttpServletRequest httpReq;
protected MockHttpServletResponse httpResp;
protected IRequest pendingReq;
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
@BeforeClass
- public static void classInitializer() throws InitializationException, ComponentInitializationException {
+ public static void classInitializer() throws Exception {
EaafOpenSaml3xInitializer.eaafInitialize();
+ mockWebServer = new MockWebServer();
+ mockServerUrl = mockWebServer.url("/sp/metadata");
}
/**
@@ -97,34 +128,236 @@ public class RedirectBindingTest {
}
@Test
- public void decodeRequestSuccess() throws MessageDecodingException, SecurityException, IOException, Pvp2Exception {
+ public void decodeRequestNoSignature() throws MessageDecodingException,
+ SecurityException, IOException, Pvp2MetadataException {
+ final String serviceUrl = "http://testservice.org";
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_wrong_sig.xml", null, "jUnit metadata resolver", null);
+
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ httpReq.setMethod("GET");
+ httpReq.setRequestURI("http://testservice.org");
+ httpReq.setQueryString("SAMLRequest=nVRNb9swDD13wP6DoXvkr%2FRjQuzCSFAgQDd0TbfDLoVi0642Wcok2kn766c4duABWw%"
+ + "2B%2BSdQj%2BfhIanF7qKXXgrFCq4SENCAeqFwXQlUJ%2BfZ0N7sht%2BnC8lpGO5Y1%2BKIe4XcDFj3nqCw7vSSkMYppboVli"
+ + "tdgGeZsk32%2BZxEN2M5o1LmWxMusBYMu1VIr29RgNmBakcNaFXBw6R0C0Yhtg3BCOBp%2FQxy%2FlcsuFMeO8Qvijvk%2BOps"
+ + "9Aak2FfHWq4Q8c4BtySHO4eomLCEuipyXURjzeVQGYRE7mLWNC22RK0xIFITzWRDPgsun4IrFn1gQ0evryx%2FE%2Bz4o5Oohv"
+ + "R6sczZjId7XgQ%2FVE%2B9Om5rj%2B%2FCjRRSzsoMyUCjwlaTHgq2ruIBaU6jEG61ayrG777RBLp%2BPR6krofyFP2Y68N402"
+ + "5%2BQ4xTi6ccPFxd9mC8Ot15NI9T7umiDpSd1nrUT4kFLkb96mZR6vzTAERKCpoEpCu6OPbTohCRThtc%2FU%2Bs3AIpuH9ygI"
+ + "hwm7cNYzXGspXSKP0I5qUP9Ruz3e2pRm1%2B00i2Fxne77ecCxRuor1l2Dy1Ifz6o%2F6%2Fso%2B78p%2Bb0%2FDz%2BGdI%2"
+ + "F&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&Signature=DOVMqh17xn4wl%2"
+ + "Byvifm4McMsBjKDVf1eqph9ss362ZEbp2nkAIXUzkNWv72I96iNK3r%2BYbAxY9dwZ8Z7jKzCGiJ9Qm34YSfPvzXWl3EVrdI86"
+ + "9U%2BH6HGIMqVew3cVdr4q3Qv9ZBIhdRxbrDu%2F%2BnMjdf8mzbgcQnfjSQiQIYWxOIXZFyxKsyrxJtIam4hoNwUT7mMN6Rjg"
+ + "zvyeS3mARsTJdcI0Vn4ItiprhLgIkD18V9WIdeSZR0gfRaFj8PKdmXCD%2FIa0cKgjhVKoiIZisV4vcthBOeDIqBORL2Ad3Xhc"
+ + "NRQ3%2BcpAf65zHGMBAv1aRy7Bmv0%2B%2BOvCavufykqI2EHtg%3D%3D");
+
+ httpReq.setParameter(HTTP_FORM_SAMLREQ, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_FORM_SAMLREQ).substring(HTTP_FORM_SAMLREQ_PARAM.length()), "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGALG, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGALG).substring(HTTP_REDIRECT_SIGALG_PARAM.length()),
+ "UTF-8"));
+
+ try {
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME,
+ comparator);
+ Assert.fail("Missing signature not detected");
+
+ } catch (final Pvp2Exception e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.02", e.getErrorId());
+
+ }
+
+ }
+
+ @Test
+ public void decodeRequestWrongEndpoint() throws MessageDecodingException,
+ SecurityException, IOException, Pvp2Exception {
+ final String serviceUrl = "http://wrongEndPoint.org";
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_wrong_sig.xml", null, "jUnit metadata resolver", null);
+
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ httpReq.setMethod("GET");
+ httpReq.setRequestURI("http://testservice.org");
+ httpReq.setQueryString("SAMLRequest=nVRNb9swDD13wP6DoXvkr%2FRjQuzCSFAgQDd0TbfDLoVi0642Wcok2kn766c4duABWw%"
+ + "2B%2BSdQj%2BfhIanF7qKXXgrFCq4SENCAeqFwXQlUJ%2BfZ0N7sht%2BnC8lpGO5Y1%2BKIe4XcDFj3nqCw7vSSkMYppboVli"
+ + "tdgGeZsk32%2BZxEN2M5o1LmWxMusBYMu1VIr29RgNmBakcNaFXBw6R0C0Yhtg3BCOBp%2FQxy%2FlcsuFMeO8Qvijvk%2BOps"
+ + "9Aak2FfHWq4Q8c4BtySHO4eomLCEuipyXURjzeVQGYRE7mLWNC22RK0xIFITzWRDPgsun4IrFn1gQ0evryx%2FE%2Bz4o5Oohv"
+ + "R6sczZjId7XgQ%2FVE%2B9Om5rj%2B%2FCjRRSzsoMyUCjwlaTHgq2ruIBaU6jEG61ayrG777RBLp%2BPR6krofyFP2Y68N402"
+ + "5%2BQ4xTi6ccPFxd9mC8Ot15NI9T7umiDpSd1nrUT4kFLkb96mZR6vzTAERKCpoEpCu6OPbTohCRThtc%2FU%2Bs3AIpuH9ygI"
+ + "hwm7cNYzXGspXSKP0I5qUP9Ruz3e2pRm1%2B00i2Fxne77ecCxRuor1l2Dy1Ifz6o%2F6%2Fso%2B78p%2Bb0%2FDz%2BGdI%2"
+ + "F&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&Signature=DOVMqh17xn4wl%2"
+ + "Byvifm4McMsBjKDVf1eqph9ss362ZEbp2nkAIXUzkNWv72I96iNK3r%2BYbAxY9dwZ8Z7jKzCGiJ9Qm34YSfPvzXWl3EVrdI86"
+ + "9U%2BH6HGIMqVew3cVdr4q3Qv9ZBIhdRxbrDu%2F%2BnMjdf8mzbgcQnfjSQiQIYWxOIXZFyxKsyrxJtIam4hoNwUT7mMN6Rjg"
+ + "zvyeS3mARsTJdcI0Vn4ItiprhLgIkD18V9WIdeSZR0gfRaFj8PKdmXCD%2FIa0cKgjhVKoiIZisV4vcthBOeDIqBORL2Ad3Xhc"
+ + "NRQ3%2BcpAf65zHGMBAv1aRy7Bmv0%2B%2BOvCavufykqI2EHtg%3D%3D");
+
+ httpReq.setParameter(HTTP_FORM_SAMLREQ, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_FORM_SAMLREQ).substring(HTTP_FORM_SAMLREQ_PARAM.length()), "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGALG, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGALG).substring(HTTP_REDIRECT_SIGALG_PARAM.length()),
+ "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGNATURE, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGNATURE).substring(HTTP_REDIRECT_SIGNATURE_PARAM.length()),
+ "UTF-8"));
+
+ try {
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME,
+ comparator);
+ Assert.fail("Wrong signature not detected");
+
+ } catch (final Pvp2Exception e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.10", e.getErrorId());
+ Assert.assertNotNull("Parameters null", e.getParams());
+ Assert.assertEquals("Wrong numer of parameters", 1, e.getParams().length);
+
+ }
+
+ }
+
+ @Test
+ public void decodeRequestWrongSignature() throws MessageDecodingException,
+ SecurityException, IOException, Pvp2Exception {
+ final String serviceUrl = "http://testservice.org";
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_wrong_sig.xml", null, "jUnit metadata resolver", null);
+
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ httpReq.setMethod("GET");
+ httpReq.setRequestURI("http://testservice.org");
+ httpReq.setQueryString("SAMLRequest=nVRNb9swDD13wP6DoXvkr%2FRjQuzCSFAgQDd0TbfDLoVi0642Wcok2kn766c4duABWw%"
+ + "2B%2BSdQj%2BfhIanF7qKXXgrFCq4SENCAeqFwXQlUJ%2BfZ0N7sht%2BnC8lpGO5Y1%2BKIe4XcDFj3nqCw7vSSkMYppboVli"
+ + "tdgGeZsk32%2BZxEN2M5o1LmWxMusBYMu1VIr29RgNmBakcNaFXBw6R0C0Yhtg3BCOBp%2FQxy%2FlcsuFMeO8Qvijvk%2BOps"
+ + "9Aak2FfHWq4Q8c4BtySHO4eomLCEuipyXURjzeVQGYRE7mLWNC22RK0xIFITzWRDPgsun4IrFn1gQ0evryx%2FE%2Bz4o5Oohv"
+ + "R6sczZjId7XgQ%2FVE%2B9Om5rj%2B%2FCjRRSzsoMyUCjwlaTHgq2ruIBaU6jEG61ayrG777RBLp%2BPR6krofyFP2Y68N402"
+ + "5%2BQ4xTi6ccPFxd9mC8Ot15NI9T7umiDpSd1nrUT4kFLkb96mZR6vzTAERKCpoEpCu6OPbTohCRThtc%2FU%2Bs3AIpuH9ygI"
+ + "hwm7cNYzXGspXSKP0I5qUP9Ruz3e2pRm1%2B00i2Fxne77ecCxRuor1l2Dy1Ifz6o%2F6%2Fso%2B78p%2Bb0%2FDz%2BGdI%2"
+ + "F&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&Signature=DOVMqh17xn4wl%2"
+ + "Byvifm4McMsBjKDVf1eqph9ss362ZEbp2nkAIXUzkNWv72I96iNK3r%2BYbAxY9dwZ8Z7jKzCGiJ9Qm34YSfPvzXWl3EVrdI86"
+ + "9U%2BH6HGIMqVew3cVdr4q3Qv9ZBIhdRxbrDu%2F%2BnMjdf8mzbgcQnfjSQiQIYWxOIXZFyxKsyrxJtIam4hoNwUT7mMN6Rjg"
+ + "zvyeS3mARsTJdcI0Vn4ItiprhLgIkD18V9WIdeSZR0gfRaFj8PKdmXCD%2FIa0cKgjhVKoiIZisV4vcthBOeDIqBORL2Ad3Xhc"
+ + "NRQ3%2BcpAf65zHGMBAv1aRy7Bmv0%2B%2BOvCavufykqI2EHtg%3D%3D");
+
+ httpReq.setParameter(HTTP_FORM_SAMLREQ, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_FORM_SAMLREQ).substring(HTTP_FORM_SAMLREQ_PARAM.length()), "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGALG, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGALG).substring(HTTP_REDIRECT_SIGALG_PARAM.length()),
+ "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGNATURE, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGNATURE).substring(HTTP_REDIRECT_SIGNATURE_PARAM.length()),
+ "UTF-8"));
+
+ try {
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME,
+ comparator);
+ Assert.fail("Wrong signature not detected");
+
+ } catch (final Pvp2Exception e) {
+ org.springframework.util.Assert.isInstanceOf(SamlSigningException.class, e, "Wrong Exception type");
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.10", e.getErrorId());
+ Assert.assertNotNull("No error params", e.getParams());
+ Assert.assertEquals("Wrong param size", 1, e.getParams().length);
+
+ }
+
+ }
+
+ @Test
+ public void decodeRequestExpired() throws MessageDecodingException,
+ SecurityException, IOException, Pvp2Exception, CredentialsNotAvailableException,
+ XMLParserException, UnmarshallingException {
final String serviceUrl = "http://testservice.org";
-
- final IPvp2MetadataProvider metadataProvider =
+
+ final IPvp2MetadataProvider metadataProvider =
metadataResolverFactory.createMetadataProvider(
- "classpath:/data/metadata_1.xml", null, "jUnit metadata resolver", null);
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null);
- final boolean isSpEndPoint = false;
final URIComparator comparator = new EaafUriCompare(serviceUrl);
httpReq.setMethod("GET");
httpReq.setRequestURI("http://testservice.org");
- httpReq.setParameter("SAMLRequest","nVRNb9swDD13wP6DoXvkr/RjQuzCSFAgQDd0TbfDLoVi0642Wcok2kn766c4duABWw++SdQj+fhIanF7qKXXgrFCq4SENCAeqFwXQlUJ+fZ0N7sht+nC8lpGO5Y1+KIe4XcDFj3nqCw7vSSkMYppboVlitdgGeZsk32+ZxEN2M5o1LmWxMusBYMu1VIr29RgNmBakcNaFXBw6R0C0Yhtg3BCOBp/Qxy/lcsuFMeO8Qvijvk+Ops9Aak2FfHWq4Q8c4BtySHO4eomLCEuipyXURjzeVQGYRE7mLWNC22RK0xIFITzWRDPgsun4IrFn1gQ0evryx/E+z4o5OohvR6sczZjId7XgQ/VE+9Om5rj+/CjRRSzsoMyUCjwlaTHgq2ruIBaU6jEG61ayrG777RBLp+PR6krofyFP2Y68N4025+Q4xTi6ccPFxd9mC8Ot15NI9T7umiDpSd1nrUT4kFLkb96mZR6vzTAERKCpoEpCu6OPbTohCRThtc/U+s3AIpuH9ygIhwm7cNYzXGspXSKP0I5qUP9Ruz3e2pRm1+00i2Fxne77ecCxRuor1l2Dy1Ifz6o/6/so+78p+b0/Dz+GdI/");
- httpReq.setParameter("SigAlg","http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
- httpReq.setParameter("Signature","DOVMqh17xn4wl+yvifm4McMsBjKDVf1eqph9ss362ZEbp2nkAIXUzkNWv72I96iNK3r+YbAxY9dwZ8Z7jKzCGiJ9Qm34YSfPvzXWl3EVrdI869U+H6HGIMqVew3cVdr4q3Qv9ZBIhdRxbrDu/+nMjdf8mzbgcQnfjSQiQIYWxOIXZFyxKsyrxJtIam4hoNwUT7mMN6RjgzvyeS3mARsTJdcI0Vn4ItiprhLgIkD18V9WIdeSZR0gfRaFj8PKdmXCD/Ia0cKgjhVKoiIZisV4vcthBOeDIqBORL2Ad3XhcNRQ3+cpAf65zHGMBAv1aRy7Bmv0++OvCavufykqI2EHtg==");
+ httpReq.setQueryString("SAMLRequest=nVRNb9swDD13wP6DoXvkj2RFJsQujAQFAnTD1nQ97FIoNu1qkyVPop20v36KYwcusPVgQ"
+ + "AeLeiQfH0mvbo6V9FowVmgVk5AGxAOV6VyoMiY%2FHm5nS3KTrCyvZFSztMFndQ9%2FGrDoOUdl2fklJo1RTHMrLFO8AsswY7v"
+ + "0yx2LaMBqo1FnWhIvtRYMulRrrWxTgdmBaUUGW5XD0aV3CEQj9g3CGeFovIU4fhuXXSiOHeNnxJr5PjqbPQOpNiXxtpuYPHGAf"
+ + "cFhnsH1MixgnucZL6JwzhdREYT53MGsbVxoi1xhTKIgCmZBNAsWD8Fn5s6na7qMwp%2FEexwUcvWQXg%2FWOZuxEO%2FrwIfqi"
+ + "XerTcXxffjJIvJZ0UEZKBT4QpJTwdZVnEOlKZTilZYt5djda22Qy6fTp9SlUP7KHzMdeO%2Ba%2FS%2FIcArx5OOHq6s%2BzFe"
+ + "H226mEep9XbTB0pO6zNoZ8U1Lkb14qZT6sDbAEWKCpoEpCtanHlp0QpIpw%2BtfqPUbAHm3D25QEY6T9mGs5jjWWjrF76GY1KF"
+ + "%2BIw6HA7WozW9a6pZC47vd9jOB4hXU9zS9gxakvxjU%2F1f2UXf%2BU3NyeR7%2FGZK%2F&SigAlg=http%3A%2F%2Fwww.w3"
+ + ".org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&Signature=JogFpk2oimCnBCgE7eZx%2B6yoJu2ZCgus5vM1opkTk"
+ + "OLM9qgNMUJJJbIeA3j2TR%2BWx3pUApnV7ed9CuTBF94b3ELkFdaZAetfLzY8gnPLCBmcYIYkwg3bK7ZQWEBJpjNoU%2BaBHXV"
+ + "OgptLUt0qRWavm%2BiPOUXRWpb0PtgvApTieRk32gBfZbuPOltWjrRCKaa2ulKBjB34LqYdAaIWaVix2sGvg128p6lC7bQ%2Fz"
+ + "wmz6j8S5Vn8snvlg48MlBldTWKSZrUERx3MwTyaB17A617XmX2QKo8fGCQ6O7FF4umFyWGAlujI%2FwqafTfPlaNX2usHynHS6"
+ + "XkH5HWCDSAe3%2BVR1w%3D%3D ");
+
+ httpReq.setParameter(HTTP_FORM_SAMLREQ, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_FORM_SAMLREQ).substring(HTTP_FORM_SAMLREQ_PARAM.length()), "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGALG, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGALG).substring(HTTP_REDIRECT_SIGALG_PARAM.length()),
+ "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGNATURE, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGNATURE).substring(HTTP_REDIRECT_SIGNATURE_PARAM.length()),
+ "UTF-8"));
+
+ try {
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME,
+ comparator);
+ Assert.fail("Expired message not detected");
+
+ } catch (final Pvp2Exception e) {
+ org.springframework.util.Assert.isInstanceOf(SamlMessageValidationException.class, e,
+ "Wrong Exception type");
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.11", e.getErrorId());
+ Assert.assertNotNull("No error params", e.getParams());
+ Assert.assertEquals("Wrong param size", 1, e.getParams().length);
+
+ }
+
+ }
+ @Test
+ public void decodeRequestSuccess() throws MessageDecodingException,
+ SecurityException, IOException, Pvp2Exception, CredentialsNotAvailableException,
+ XMLParserException, UnmarshallingException {
+ final String serviceUrl = "http://testservice.org";
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null);
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ httpReq.setMethod("GET");
+ httpReq.setRequestURI("http://testservice.org");
+ httpReq.setQueryString(generateAuthnRequest(credentialProvider.getIdpMetaDataSigningCredential()));
+
+ httpReq.setParameter(HTTP_FORM_SAMLREQ, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_FORM_SAMLREQ).substring(HTTP_FORM_SAMLREQ_PARAM.length()), "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGALG, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGALG).substring(HTTP_REDIRECT_SIGALG_PARAM.length()),
+ "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGNATURE, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGNATURE).substring(HTTP_REDIRECT_SIGNATURE_PARAM.length()),
+ "UTF-8"));
final InboundMessageInterface msg =
- bindingImpl.decode(httpReq, httpResp, metadataProvider, isSpEndPoint, comparator);
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME,
+ comparator);
Assert.assertNotNull("PVP msg is null", msg);
Assert.assertNull("RelayState is not null", msg.getRelayState());
Assert.assertNotNull("AuthnReq is null", msg.getInboundMessage());
Assert.assertNotNull("EntityId is null", msg.getEntityID());
- Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg.getEntityID());
- Assert.assertFalse("Wrong isVerified flag", msg.isVerified());
+ Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg
+ .getEntityID());
+ Assert.assertTrue("Wrong isVerified flag", msg.isVerified());
}
@@ -143,88 +376,123 @@ public class RedirectBindingTest {
final IPvp2MetadataProvider metadataProvider = null;
- final boolean isSpEndPoint = false;
final URIComparator comparator = new EaafUriCompare(serviceUrl);
-
final InboundMessageInterface msg =
- bindingImpl.decode(httpReq, httpResp, metadataProvider, isSpEndPoint, comparator);
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME,
+ comparator);
Assert.assertNotNull("PVP msg is null", msg);
Assert.assertNotNull("RelayState is not null", msg.getRelayState());
Assert.assertEquals("RelayState not match", relayState, msg.getRelayState());
Assert.assertNotNull("AuthnReq is null", msg.getInboundMessage());
Assert.assertNotNull("EntityId is null", msg.getEntityID());
- Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg.getEntityID());
+ Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg
+ .getEntityID());
Assert.assertFalse("Wrong isVerified flag", msg.isVerified());
}
- @Ignore
@Test
- public void decodeResponseSuccess() throws MessageDecodingException, SecurityException, IOException, Pvp2Exception {
+ public void decodeResponseSuccess() throws MessageDecodingException, SecurityException, IOException,
+ Pvp2Exception, CredentialsNotAvailableException, XMLParserException, UnmarshallingException {
final String serviceUrl = "http://testservice.org";
- final IPvp2MetadataProvider metadataProvider = null;
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null);
- final boolean isSpEndPoint = false;
final URIComparator comparator = new EaafUriCompare(serviceUrl);
- final String b64AuthnReq = Base64.getEncoder().encodeToString(IOUtils.toByteArray(
- RedirectBindingTest.class.getResourceAsStream("/data/Response_with_sig_1.xml")));
- httpReq.setMethod("POST");
- httpReq.addParameter("SAMLRequest", b64AuthnReq);
+ httpReq.setMethod("GET");
+ httpReq.setRequestURI("http://testservice.org");
+ httpReq.setQueryString(generateResponse(credentialProvider.getIdpMetaDataSigningCredential()));
+ httpReq.setParameter(HTTP_FORM_SAMLRESP, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_FORM_SAMLRESP).substring(HTTP_FORM_SAMLRESP_PARM.length()), "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGALG, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGALG).substring(HTTP_REDIRECT_SIGALG_PARAM.length()),
+ "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGNATURE, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGNATURE).substring(HTTP_REDIRECT_SIGNATURE_PARAM.length()),
+ "UTF-8"));
final InboundMessageInterface msg =
- bindingImpl.decode(httpReq, httpResp, metadataProvider, isSpEndPoint, comparator);
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME,
+ comparator);
Assert.assertNotNull("PVP msg is null", msg);
Assert.assertNull("RelayState is not null", msg.getRelayState());
Assert.assertNotNull("Response is null", msg.getInboundMessage());
Assert.assertNotNull("EntityId is null", msg.getEntityID());
- Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp/metadata", msg.getEntityID());
- Assert.assertFalse("Wrong isVerified flag", msg.isVerified());
+ Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg
+ .getEntityID());
+ Assert.assertTrue("Wrong isVerified flag", msg.isVerified());
}
- @Ignore
@Test
- public void decodeResponseSuccessWithRelayState() throws MessageDecodingException, SecurityException,
- IOException, Pvp2Exception {
+ public void decodeResponseSuccessWithRelayStateAndMetadataReload() throws MessageDecodingException,
+ SecurityException, IOException, Pvp2Exception, CredentialsNotAvailableException,
+ XMLParserException, UnmarshallingException {
final String serviceUrl = "http://testservice.org";
final String relayState = RandomStringUtils.randomAlphanumeric(10);
- final String b64AuthnReq = Base64.getEncoder().encodeToString(IOUtils.toByteArray(
- RedirectBindingTest.class.getResourceAsStream("/data/Response_with_sig_1.xml")));
- httpReq.setMethod("POST");
- httpReq.addParameter("SAMLRequest", b64AuthnReq);
- httpReq.addParameter("RelayState", relayState);
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(new String(IOUtils.toByteArray(
+ MetadataResolverTest.class.getResourceAsStream(
+ "/data/pvp_metadata_wrong_sig.xml")), "UTF-8"))
+ .setHeader("Content-Type", "text/xml"));
- final IPvp2MetadataProvider metadataProvider = null;
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(new String(IOUtils.toByteArray(
+ MetadataResolverTest.class.getResourceAsStream(
+ "/data/pvp_metadata_junit_keystore.xml")), "UTF-8"))
+ .setHeader("Content-Type", "text/xml"));
- final boolean isSpEndPoint = false;
- final URIComparator comparator = new EaafUriCompare(serviceUrl);
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ mockServerUrl.url().toString(),
+ null, "jUnit test", httpClientFactory.getHttpClient());
+ httpReq.setMethod("GET");
+ httpReq.setRequestURI("http://testservice.org");
+ httpReq.setParameter(HTTP_FORM_RELAYSTATE, relayState);
+ httpReq.setQueryString(generateResponse(credentialProvider.getIdpMetaDataSigningCredential()));
+
+ httpReq.setParameter(HTTP_FORM_SAMLRESP, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_FORM_SAMLRESP).substring(HTTP_FORM_SAMLRESP_PARM.length()), "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGALG, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGALG).substring(HTTP_REDIRECT_SIGALG_PARAM.length()),
+ "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGNATURE, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGNATURE).substring(HTTP_REDIRECT_SIGNATURE_PARAM.length()),
+ "UTF-8"));
+
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
final InboundMessageInterface msg =
- bindingImpl.decode(httpReq, httpResp, metadataProvider, isSpEndPoint, comparator);
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME,
+ comparator);
Assert.assertNotNull("PVP msg is null", msg);
- Assert.assertNotNull("RelayState is not null", msg.getRelayState());
+ Assert.assertNotNull("RelayState is null", msg.getRelayState());
Assert.assertEquals("RelayState not match", relayState, msg.getRelayState());
Assert.assertNotNull("Response is null", msg.getInboundMessage());
Assert.assertNotNull("EntityId is null", msg.getEntityID());
- Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp/metadata", msg.getEntityID());
- Assert.assertFalse("Wrong isVerified flag", msg.isVerified());
+ Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg
+ .getEntityID());
+ Assert.assertTrue("Wrong isVerified flag", msg.isVerified());
}
@Test
public void encodeRequestSuccess() throws MessageDecodingException, SecurityException,
MessageEncodingException, XMLParserException, UnmarshallingException,
- CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException, Pvp2Exception {
- //build test data
+ CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException,
+ Pvp2Exception {
+ // build test data
final String serviceUrl = "http://testservice.org";
final String relayState = null;
final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
@@ -234,7 +502,7 @@ public class RedirectBindingTest {
bindingImpl.encodeRequest(httpReq, httpResp, authnReq, serviceUrl, relayState,
credentialProvider.getIdpMetaDataSigningCredential(), pendingReq);
- //validate
+ // validate
Assert.assertEquals("http StatusCode", 302, httpResp.getStatus());
Assert.assertEquals("PVP msg is null", 0, httpResp.getContentLength());
@@ -246,33 +514,33 @@ public class RedirectBindingTest {
Assert.assertFalse("Location header is empty", locationHeader.isEmpty());
Assert.assertTrue("Wrong redirect URL",
- locationHeader.startsWith(serviceUrl + "?" + HTTP_FORM_SAMLREQ));
+ locationHeader.startsWith(serviceUrl + "?" + HTTP_FORM_SAMLREQ_PARAM));
- final String respSamlMsg = checkMessagePart(locationHeader, HTTP_FORM_SAMLREQ, true);
+ final String respSamlMsg = checkMessagePart(locationHeader, HTTP_FORM_SAMLREQ_PARAM, true);
Assert.assertNotNull("Saml msg is null", respSamlMsg);
Assert.assertFalse("Saml msg is empty", respSamlMsg.isEmpty());
- final String sigAlg = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGALG, true);
+ final String sigAlg = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGALG_PARAM, true);
Assert.assertNotNull("SigAlg is null", sigAlg);
Assert.assertFalse("SigAlg is empty", sigAlg.isEmpty());
Assert.assertEquals("SigAlg not match", PvpConstants.DEFAULT_SIGNING_METHODE_RSA,
URLDecoder.decode(sigAlg, "UTF-8"));
- final String samlSig = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGNATURE, true);
+ final String samlSig = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGNATURE_PARAM, true);
Assert.assertNotNull("Saml signature null", samlSig);
Assert.assertFalse("Saml signature is empty", samlSig.isEmpty());
- final String respRelayState = checkMessagePart(locationHeader, HTTP_FORM_RELAYSTATE, false);
+ final String respRelayState = checkMessagePart(locationHeader, HTTP_FORM_RELAYSTATE_PARAM, false);
Assert.assertNull("RelayState parameter", respRelayState);
}
-
@Test
public void encodeRequestSuccessEcdsa() throws MessageDecodingException, SecurityException,
MessageEncodingException, XMLParserException, UnmarshallingException,
- CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException, Pvp2Exception {
- //build test data
+ CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException,
+ Pvp2Exception {
+ // build test data
final String serviceUrl = "http://testservice.org";
final String relayState = null;
final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
@@ -282,8 +550,8 @@ public class RedirectBindingTest {
bindingImpl.encodeRequest(httpReq, httpResp, authnReq, serviceUrl, relayState,
credentialProvider.getIdpAssertionSigningCredential(), pendingReq);
- //validate
- //validate
+ // validate
+ // validate
Assert.assertEquals("http StatusCode", 302, httpResp.getStatus());
Assert.assertEquals("PVP msg is null", 0, httpResp.getContentLength());
@@ -295,34 +563,34 @@ public class RedirectBindingTest {
Assert.assertFalse("Location header is empty", locationHeader.isEmpty());
Assert.assertTrue("Wrong redirect URL",
- locationHeader.startsWith(serviceUrl + "?" + HTTP_FORM_SAMLREQ));
+ locationHeader.startsWith(serviceUrl + "?" + HTTP_FORM_SAMLREQ_PARAM));
- final String respSamlMsg = checkMessagePart(locationHeader, HTTP_FORM_SAMLREQ, true);
+ final String respSamlMsg = checkMessagePart(locationHeader, HTTP_FORM_SAMLREQ_PARAM, true);
Assert.assertNotNull("Saml msg is null", respSamlMsg);
Assert.assertFalse("Saml msg is empty", respSamlMsg.isEmpty());
- final String sigAlg = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGALG, true);
+ final String sigAlg = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGALG_PARAM, true);
Assert.assertNotNull("SigAlg is null", sigAlg);
Assert.assertFalse("SigAlg is empty", sigAlg.isEmpty());
Assert.assertEquals("SigAlg not match", PvpConstants.DEFAULT_SIGNING_METHODE_EC,
URLDecoder.decode(sigAlg, "UTF-8"));
- final String samlSig = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGNATURE, true);
+ final String samlSig = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGNATURE_PARAM, true);
Assert.assertNotNull("Saml signature null", samlSig);
Assert.assertFalse("Saml signature is empty", samlSig.isEmpty());
- final String respRelayState = checkMessagePart(locationHeader, HTTP_FORM_RELAYSTATE, false);
+ final String respRelayState = checkMessagePart(locationHeader, HTTP_FORM_RELAYSTATE_PARAM, false);
Assert.assertNull("RelayState parameter", respRelayState);
-
}
@Test
public void encodeRequestSuccessWithRelayState() throws MessageDecodingException, SecurityException,
MessageEncodingException, XMLParserException, UnmarshallingException,
- CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException, Pvp2Exception {
+ CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException,
+ Pvp2Exception {
- //build test data
+ // build test data
final String serviceUrl = "http://testservice.org";
final String relayState = RandomStringUtils.randomAlphabetic(10);
final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
@@ -332,8 +600,7 @@ public class RedirectBindingTest {
bindingImpl.encodeRequest(httpReq, httpResp, authnReq, serviceUrl, relayState,
credentialProvider.getIdpMetaDataSigningCredential(), pendingReq);
-
- //validate
+ // validate
Assert.assertEquals("http StatusCode", 302, httpResp.getStatus());
Assert.assertEquals("PVP msg is null", 0, httpResp.getContentLength());
@@ -345,36 +612,36 @@ public class RedirectBindingTest {
Assert.assertFalse("Location header is empty", locationHeader.isEmpty());
Assert.assertTrue("Wrong redirect URL",
- locationHeader.startsWith(serviceUrl + "?" + HTTP_FORM_SAMLREQ));
+ locationHeader.startsWith(serviceUrl + "?" + HTTP_FORM_SAMLREQ_PARAM));
- final String respSamlMsg = checkMessagePart(locationHeader, HTTP_FORM_SAMLREQ, true);
+ final String respSamlMsg = checkMessagePart(locationHeader, HTTP_FORM_SAMLREQ_PARAM, true);
Assert.assertNotNull("Saml msg is null", respSamlMsg);
Assert.assertFalse("Saml msg is empty", respSamlMsg.isEmpty());
- final String sigAlg = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGALG, true);
+ final String sigAlg = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGALG_PARAM, true);
Assert.assertNotNull("SigAlg is null", sigAlg);
Assert.assertFalse("SigAlg is empty", sigAlg.isEmpty());
Assert.assertEquals("SigAlg not match", PvpConstants.DEFAULT_SIGNING_METHODE_RSA,
URLDecoder.decode(sigAlg, "UTF-8"));
- final String samlSig = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGNATURE, true);
+ final String samlSig = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGNATURE_PARAM, true);
Assert.assertNotNull("Saml signature null", samlSig);
Assert.assertFalse("Saml signature is empty", samlSig.isEmpty());
- final String respRelayState = checkMessagePart(locationHeader, HTTP_FORM_RELAYSTATE, false);
+ final String respRelayState = checkMessagePart(locationHeader, HTTP_FORM_RELAYSTATE_PARAM, false);
Assert.assertNotNull("RelayState parameter", respRelayState);
Assert.assertEquals("RelayState not match", relayState,
URLDecoder.decode(respRelayState, "UTF-8"));
-
}
@Test
public void encodeResponseSuccessWithRelayState() throws MessageDecodingException, SecurityException,
MessageEncodingException, XMLParserException, UnmarshallingException,
- CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException, Pvp2Exception {
+ CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException,
+ Pvp2Exception {
- //build test data
+ // build test data
final String serviceUrl = "http://testservice.org";
final String relayState = RandomStringUtils.randomAlphabetic(10);
final StatusResponseType authnReq = (StatusResponseType) XMLObjectSupport.unmarshallFromInputStream(
@@ -384,8 +651,7 @@ public class RedirectBindingTest {
bindingImpl.encodeResponse(httpReq, httpResp, authnReq, serviceUrl, relayState,
credentialProvider.getIdpMetaDataSigningCredential(), pendingReq);
-
- //validate
+ // validate
Assert.assertEquals("http StatusCode", 302, httpResp.getStatus());
Assert.assertEquals("PVP msg is null", 0, httpResp.getContentLength());
@@ -397,23 +663,23 @@ public class RedirectBindingTest {
Assert.assertFalse("Location header is empty", locationHeader.isEmpty());
Assert.assertTrue("Wrong redirect URL",
- locationHeader.startsWith(serviceUrl + "?" + HTTP_FORM_SAMLRESP));
+ locationHeader.startsWith(serviceUrl + "?" + HTTP_FORM_SAMLRESP_PARM));
- final String respSamlMsg = checkMessagePart(locationHeader, HTTP_FORM_SAMLRESP, true);
+ final String respSamlMsg = checkMessagePart(locationHeader, HTTP_FORM_SAMLRESP_PARM, true);
Assert.assertNotNull("Saml msg is null", respSamlMsg);
Assert.assertFalse("Saml msg is empty", respSamlMsg.isEmpty());
- final String sigAlg = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGALG, true);
+ final String sigAlg = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGALG_PARAM, true);
Assert.assertNotNull("SigAlg is null", sigAlg);
Assert.assertFalse("SigAlg is empty", sigAlg.isEmpty());
Assert.assertEquals("SigAlg not match", PvpConstants.DEFAULT_SIGNING_METHODE_RSA,
URLDecoder.decode(sigAlg, "UTF-8"));
- final String samlSig = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGNATURE, true);
+ final String samlSig = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGNATURE_PARAM, true);
Assert.assertNotNull("Saml signature null", samlSig);
Assert.assertFalse("Saml signature is empty", samlSig.isEmpty());
- final String respRelayState = checkMessagePart(locationHeader, HTTP_FORM_RELAYSTATE, false);
+ final String respRelayState = checkMessagePart(locationHeader, HTTP_FORM_RELAYSTATE_PARAM, false);
Assert.assertNotNull("RelayState parameter", respRelayState);
Assert.assertEquals("RelayState not match", relayState,
URLDecoder.decode(respRelayState, "UTF-8"));
@@ -423,9 +689,10 @@ public class RedirectBindingTest {
@Test
public void encodeResponseSuccess() throws MessageDecodingException, SecurityException,
MessageEncodingException, XMLParserException, UnmarshallingException,
- CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException, Pvp2Exception {
+ CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException,
+ Pvp2Exception {
- //build test data
+ // build test data
final String serviceUrl = "http://testservice.org";
final String relayState = null;
final StatusResponseType authnReq = (StatusResponseType) XMLObjectSupport.unmarshallFromInputStream(
@@ -435,8 +702,7 @@ public class RedirectBindingTest {
bindingImpl.encodeResponse(httpReq, httpResp, authnReq, serviceUrl, relayState,
credentialProvider.getIdpMetaDataSigningCredential(), pendingReq);
-
- //validate
+ // validate
Assert.assertEquals("http StatusCode", 302, httpResp.getStatus());
Assert.assertEquals("PVP msg is null", 0, httpResp.getContentLength());
@@ -448,23 +714,23 @@ public class RedirectBindingTest {
Assert.assertFalse("Location header is empty", locationHeader.isEmpty());
Assert.assertTrue("Wrong redirect URL",
- locationHeader.startsWith(serviceUrl + "?" + HTTP_FORM_SAMLRESP));
+ locationHeader.startsWith(serviceUrl + "?" + HTTP_FORM_SAMLRESP_PARM));
- final String respSamlMsg = checkMessagePart(locationHeader, HTTP_FORM_SAMLRESP, true);
+ final String respSamlMsg = checkMessagePart(locationHeader, HTTP_FORM_SAMLRESP_PARM, true);
Assert.assertNotNull("Saml msg is null", respSamlMsg);
Assert.assertFalse("Saml msg is empty", respSamlMsg.isEmpty());
- final String sigAlg = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGALG, true);
+ final String sigAlg = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGALG_PARAM, true);
Assert.assertNotNull("SigAlg is null", sigAlg);
Assert.assertFalse("SigAlg is empty", sigAlg.isEmpty());
Assert.assertEquals("SigAlg not match", PvpConstants.DEFAULT_SIGNING_METHODE_RSA,
URLDecoder.decode(sigAlg, "UTF-8"));
- final String samlSig = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGNATURE, true);
+ final String samlSig = checkMessagePart(locationHeader, HTTP_REDIRECT_SIGNATURE_PARAM, true);
Assert.assertNotNull("Saml signature null", samlSig);
Assert.assertFalse("Saml signature is empty", samlSig.isEmpty());
- final String respRelayState = checkMessagePart(locationHeader, HTTP_FORM_RELAYSTATE, false);
+ final String respRelayState = checkMessagePart(locationHeader, HTTP_FORM_RELAYSTATE_PARAM, false);
Assert.assertNull("RelayState parameter", respRelayState);
}
@@ -490,4 +756,45 @@ public class RedirectBindingTest {
}
+ private String generateAuthnRequest(EaafX509Credential credential) throws Pvp2Exception,
+ XMLParserException, UnmarshallingException {
+ final MockHttpServletRequest intHttpReq = new MockHttpServletRequest();
+ final MockHttpServletResponse intHttpResp = new MockHttpServletResponse();
+
+ final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ RedirectBindingTest.class.getResourceAsStream("/data/AuthRequest_without_sig_1.xml"));
+ authnReq.setIssueInstant(DateTime.now());
+
+ bindingImpl.encodeRequest(intHttpReq, intHttpResp, authnReq, "http://testservice.org", null,
+ credential, pendingReq);
+
+ Assert.assertEquals("http StatusCode", 302, intHttpResp.getStatus());
+ final String locationHeader = intHttpResp.getHeader("Location");
+ Assert.assertNotNull("Location header is null", locationHeader);
+ return locationHeader.split("\\?")[1];
+
+ }
+
+ private String generateResponse(EaafX509Credential credential) throws Pvp2Exception,
+ XMLParserException, UnmarshallingException {
+ new MockHttpServletRequest();
+ final MockHttpServletRequest intHttpReq = new MockHttpServletRequest();
+ final MockHttpServletResponse intHttpResp = new MockHttpServletResponse();
+
+ final StatusResponseType authnReq = (StatusResponseType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ RedirectBindingTest.class.getResourceAsStream("/data/Response_without_sig_1.xml"));
+ authnReq.setIssueInstant(DateTime.now());
+
+ bindingImpl.encodeResponse(intHttpReq, intHttpResp, authnReq, "http://testservice.org", null,
+ credential, pendingReq);
+
+ Assert.assertEquals("http StatusCode", 302, intHttpResp.getStatus());
+ final String locationHeader = intHttpResp.getHeader("Location");
+ Assert.assertNotNull("Location header is null", locationHeader);
+ return locationHeader.split("\\?")[1];
+
+ }
+
}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/SoapBindingTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/SoapBindingTest.java
new file mode 100644
index 00000000..1125d30e
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/SoapBindingTest.java
@@ -0,0 +1,214 @@
+package at.gv.egiz.eaaf.modules.pvp2.test.binding;
+
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
+import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+import at.gv.egiz.eaaf.modules.pvp2.impl.binding.SoapBinding;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
+
+import org.joda.time.DateTime;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.core.xml.io.Marshaller;
+import org.opensaml.core.xml.io.MarshallingException;
+import org.opensaml.core.xml.io.UnmarshallingException;
+import org.opensaml.core.xml.util.XMLObjectSupport;
+import org.opensaml.saml.saml2.core.RequestAbstractType;
+import org.opensaml.saml.saml2.core.StatusResponseType;
+import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.soap.soap11.Envelope;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.net.URIComparator;
+import net.shibboleth.utilities.java.support.xml.SerializeSupport;
+import net.shibboleth.utilities.java.support.xml.XMLParserException;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration({"/spring/test_eaaf_pvp.beans.xml"})
+@TestPropertySource(locations = {"/config/config_1.props"})
+public class SoapBindingTest {
+
+ @Autowired private SoapBinding bindingImpl;
+ @Autowired private PvpMetadataResolverFactory metadataResolverFactory;
+ @Autowired private DummyCredentialProvider credentialProvider;
+
+ protected MockHttpServletRequest httpReq;
+ protected MockHttpServletResponse httpResp;
+ protected IRequest pendingReq;
+
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void classInitializer() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ }
+
+ /**
+ * Test initializer.
+ *
+ */
+ @Before
+ public void initialize() {
+ httpReq = new MockHttpServletRequest();
+ httpResp = new MockHttpServletResponse();
+
+ pendingReq = new TestRequestImpl();
+
+ }
+
+ @Test
+ public void withoutSig() throws Pvp2Exception, MarshallingException, XMLParserException, UnmarshallingException {
+ final String serviceUrl = "https://localhost/pvp2/post";
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null);
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ final RequestAbstractType payload = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ PostBindingTest.class.getResourceAsStream("/data/AuthRequest_without_sig_1.xml"));
+ payload.setIssueInstant(DateTime.now());
+ final Envelope enveloped = Saml2Utils.buildSoap11Envelope(payload);
+ final Marshaller marshaller = Constraint.isNotNull(
+ XMLObjectProviderRegistrySupport.getMarshallerFactory().getMarshaller(enveloped),
+ "SOAP Envelope marshaller not available");
+ final ByteArrayOutputStream arrayOut = new ByteArrayOutputStream();
+ SerializeSupport.writeNode(marshaller.marshall(enveloped), arrayOut);
+ httpReq.setMethod("POST");
+ httpReq.setContentType("text/xml");
+ httpReq.setContent(arrayOut.toByteArray());
+
+
+ try {
+ bindingImpl.decode(httpReq, httpResp, metadataProvider,
+ SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator);
+ Assert.fail("Missing signature not detected");
+
+ } catch (final Pvp2Exception e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.02", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ public void wrongSignature() throws Pvp2Exception, MarshallingException, XMLParserException, UnmarshallingException {
+ final String serviceUrl = "https://localhost/pvp2/post";
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null);
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ final RequestAbstractType payload = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ PostBindingTest.class.getResourceAsStream("/data/AuthRequest_with_sig_1.xml"));
+ payload.setIssueInstant(DateTime.now());
+ final Envelope enveloped = Saml2Utils.buildSoap11Envelope(payload);
+ final Marshaller marshaller = Constraint.isNotNull(
+ XMLObjectProviderRegistrySupport.getMarshallerFactory().getMarshaller(enveloped),
+ "SOAP Envelope marshaller not available");
+ final ByteArrayOutputStream arrayOut = new ByteArrayOutputStream();
+ SerializeSupport.writeNode(marshaller.marshall(enveloped), arrayOut);
+ httpReq.setMethod("POST");
+ httpReq.setContentType("text/xml");
+ httpReq.setContent(arrayOut.toByteArray());
+
+
+ try {
+ bindingImpl.decode(httpReq, httpResp, metadataProvider,
+ SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator);
+ Assert.fail("Missing signature not detected");
+
+ } catch (final Pvp2Exception e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.10", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ public void validSignature() throws Pvp2Exception, MarshallingException, XMLParserException,
+ UnmarshallingException, CredentialsNotAvailableException {
+ final String serviceUrl = "https://localhost/pvp2/post";
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null);
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ final RequestAbstractType payload = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ PostBindingTest.class.getResourceAsStream("/data/AuthRequest_with_sig_1.xml"));
+ payload.setIssueInstant(DateTime.now());
+ final RequestAbstractType signedPayload = Saml2Utils.signSamlObject(
+ payload, credentialProvider.getIdpMetaDataSigningCredential(), true);
+
+ final Envelope enveloped = Saml2Utils.buildSoap11Envelope(signedPayload);
+ final Marshaller marshaller = Constraint.isNotNull(
+ XMLObjectProviderRegistrySupport.getMarshallerFactory().getMarshaller(enveloped),
+ "SOAP Envelope marshaller not available");
+ final ByteArrayOutputStream arrayOut = new ByteArrayOutputStream();
+ SerializeSupport.writeNode(marshaller.marshall(enveloped), arrayOut);
+ httpReq.setMethod("POST");
+ httpReq.setContentType("text/xml");
+ httpReq.setContent(arrayOut.toByteArray());
+
+
+ final InboundMessageInterface msg =
+ bindingImpl.decode(httpReq, httpResp, metadataProvider,
+ SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator);
+
+ Assert.assertNotNull("Inbound msg is null", msg);
+ Assert.assertNotNull("AuthnReq is null", msg.getInboundMessage());
+ Assert.assertNotNull("EntityId is null", msg.getEntityID());
+ Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg.getEntityID());
+ Assert.assertTrue("Wrong isVerified flag", msg.isVerified());
+
+ }
+
+ @Test
+ public void encodeResponse() throws XMLParserException, UnmarshallingException,
+ Pvp2Exception, CredentialsNotAvailableException, UnsupportedEncodingException {
+ final String serviceUrl = "http://testservice.org";
+
+ final StatusResponseType response = (StatusResponseType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ PostBindingTest.class.getResourceAsStream("/data/Response_without_sig_1.xml"));
+
+ bindingImpl.encodeResponse(httpReq, httpResp, response, serviceUrl, null,
+ credentialProvider.getIdpMetaDataSigningCredential(), pendingReq);
+
+ Assert.assertEquals("http StatusCode", 200, httpResp.getStatus());
+ Assert.assertNotNull("PVP msg is null", httpResp.getContentLength());
+
+ Assert.assertEquals("ContentType", "text/xml", httpResp.getContentType());
+ Assert.assertEquals("Encoding", "UTF-8", httpResp.getCharacterEncoding());
+
+ final String http = httpResp.getContentAsString();
+ Assert.assertNotNull("http body is null", http);
+ Assert.assertFalse("http body is empty", http.isEmpty());
+
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataBuilderTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataBuilderTest.java
new file mode 100644
index 00000000..2d46f102
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataBuilderTest.java
@@ -0,0 +1,298 @@
+package at.gv.egiz.eaaf.modules.pvp2.test.metadata;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.core.xml.io.MarshallingException;
+import org.opensaml.core.xml.io.UnmarshallingException;
+import org.opensaml.core.xml.util.XMLObjectSupport;
+import org.opensaml.saml.common.xml.SAMLConstants;
+import org.opensaml.saml.saml2.core.Attribute;
+import org.opensaml.saml.saml2.core.NameIDType;
+import org.opensaml.saml.saml2.metadata.ContactPerson;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.Organization;
+import org.opensaml.saml.saml2.metadata.RequestedAttribute;
+import org.opensaml.saml.security.impl.SAMLSignatureProfileValidator;
+import org.opensaml.security.SecurityException;
+import org.opensaml.security.credential.Credential;
+import org.opensaml.security.x509.BasicX509Credential;
+import org.opensaml.xmlsec.signature.support.SignatureException;
+import org.opensaml.xmlsec.signature.support.SignatureValidator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import net.shibboleth.utilities.java.support.xml.XMLParserException;
+
+
+
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration({ "/spring/test_eaaf_pvp.beans.xml" })
+@TestPropertySource(locations = { "/config/config_1.props" })
+public class MetadataBuilderTest {
+
+ @Autowired private PvpMetadataBuilder metadataBuilder;
+ @Autowired private DummyCredentialProvider credentialProvider;
+
+ private static CertificateFactory fact;
+
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void classInitializer() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ fact = CertificateFactory.getInstance("X.509");
+ }
+
+ @Test
+ public void buildIdpMetadata() throws CredentialsNotAvailableException, EaafException,
+ SecurityException, TransformerFactoryConfigurationError, MarshallingException,
+ TransformerException, ParserConfigurationException, IOException, SignatureException,
+ XMLParserException, UnmarshallingException, CertificateException {
+
+ final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(false, true);
+
+ //generate metadata
+ final String metadata = metadataBuilder.buildPvpMetadata(config);
+
+ //validate
+ final EntityDescriptor entity = validateMetadata(metadata);
+ Assert.assertNotNull("IDPSSODescr. is null", entity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS));
+ Assert.assertNull("IDPSSODescr. is null", entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS));
+
+ }
+
+ @Test
+ public void buildSpMetadata() throws CredentialsNotAvailableException, EaafException,
+ SecurityException, TransformerFactoryConfigurationError, MarshallingException,
+ TransformerException, ParserConfigurationException, IOException, SignatureException,
+ XMLParserException, UnmarshallingException, CertificateException {
+
+ final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(true, false);
+
+ //generate metadata
+ final String metadata = metadataBuilder.buildPvpMetadata(config);
+
+ //validate
+ final EntityDescriptor entity = validateMetadata(metadata);
+ Assert.assertNull("IDPSSODescr. is null", entity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS));
+ Assert.assertNotNull("IDPSSODescr. is null", entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS));
+
+ }
+
+ @Test
+ public void buildSpAndIdpMetadata() throws CredentialsNotAvailableException, EaafException,
+ SecurityException, TransformerFactoryConfigurationError, MarshallingException,
+ TransformerException, ParserConfigurationException, IOException, SignatureException,
+ XMLParserException, UnmarshallingException, CertificateException {
+
+ final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(true, true);
+
+ //generate metadata
+ final String metadata = metadataBuilder.buildPvpMetadata(config);
+
+ //validate
+ final EntityDescriptor entity = validateMetadata(metadata);
+ Assert.assertNotNull("IDPSSODescr. is null", entity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS));
+ Assert.assertNotNull("IDPSSODescr. is null", entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS));
+
+ }
+
+ private EntityDescriptor validateMetadata(String metadata) throws UnsupportedEncodingException,
+ XMLParserException, UnmarshallingException, SignatureException, CertificateException {
+ Assert.assertNotNull("Metadata is null", metadata);
+ Assert.assertFalse("Metadata is empty", metadata.isEmpty());
+
+ final EntityDescriptor entity = (EntityDescriptor) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ new ByteArrayInputStream(metadata.getBytes("UTF-8")));
+
+ Assert.assertNotNull("Unmarshalling failed", entity);
+ Assert.assertNotNull("EntityId is null", entity.getEntityID());
+
+ Assert.assertNotNull("Signature is null", entity.getSignature());
+ final SAMLSignatureProfileValidator sigValidator = new SAMLSignatureProfileValidator();
+ sigValidator.validate(entity.getSignature());
+
+ final Credential cred = new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/junit_metadata_sig_cert.crt")));
+ SignatureValidator.validate(entity.getSignature(), cred);
+
+ return entity;
+ }
+
+ private IPvpMetadataBuilderConfiguration idpMetadataConfig(boolean buildSpInfos, boolean buildIdpInfos) {
+ return new IPvpMetadataBuilderConfiguration() {
+
+ @Override
+ public boolean wantAuthnRequestSigned() {
+ return true;
+ }
+
+ @Override
+ public boolean wantAssertionSigned() {
+ return true;
+ }
+
+ @Override
+ public String getSpSloSoapBindingUrl() {
+ return RandomStringUtils.randomAlphabetic(10);
+
+ }
+
+ @Override
+ public String getSpSloRedirectBindingUrl() {
+ return RandomStringUtils.randomAlphabetic(10);
+
+ }
+
+ @Override
+ public String getSpSloPostBindingUrl() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public Collection<RequestedAttribute> getSpRequiredAttributes() {
+ return null;
+ }
+
+ @Override
+ public String getSpNameForLogging() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public String getSpAssertionConsumerServiceRedirectBindingUrl() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public String getSpAssertionConsumerServicePostBindingUrl() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public List<String> getSpAllowedNameIdTypes() {
+ return Arrays.asList(NameIDType.PERSISTENT);
+ }
+
+ @Override
+ public Credential getRequestorResponseSigningCredentials() throws CredentialsNotAvailableException {
+ return credentialProvider.getIdpAssertionSigningCredential();
+ }
+
+ @Override
+ public Organization getOrgansiationInformation() {
+ return null;
+ }
+
+ @Override
+ public int getMetadataValidUntil() {
+ return 10;
+ }
+
+ @Override
+ public EaafX509Credential getMetadataSigningCredentials() throws CredentialsNotAvailableException {
+ return credentialProvider.getIdpMetaDataSigningCredential();
+ }
+
+ @Override
+ public String getIdpWebSsoRedirectBindingUrl() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public String getIdpWebSsoPostBindingUrl() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public String getIdpSloRedirectBindingUrl() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public String getIdpSloPostBindingUrl() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public List<String> getIdpPossibleNameIdTypes() {
+ return Arrays.asList(NameIDType.PERSISTENT);
+ }
+
+ @Override
+ public List<Attribute> getIdpPossibleAttributes() {
+ return null;
+ }
+
+ @Override
+ public String getEntityID() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public String getEntityFriendlyName() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public Credential getEncryptionCredentials() throws CredentialsNotAvailableException {
+ return credentialProvider.getIdpAssertionSigningCredential();
+ }
+
+ @Override
+ public List<ContactPerson> getContactPersonInformation() {
+ return null;
+ }
+
+ @Override
+ public boolean buildSpSsoDescriptor() {
+ return buildSpInfos;
+ }
+
+ @Override
+ public boolean buildIdpSsoDescriptor() {
+ return buildIdpInfos;
+ }
+
+ @Override
+ public boolean buildEntitiesDescriptorAsRootElement() {
+ return false;
+ }
+ };
+ }
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataResolverTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataResolverTest.java
new file mode 100644
index 00000000..f40fbc74
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataResolverTest.java
@@ -0,0 +1,725 @@
+package at.gv.egiz.eaaf.modules.pvp2.test.metadata;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.transform.TransformerException;
+
+import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2InternalErrorException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.PvpEntityCategoryFilter;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.SchemaValidationFilter;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.SimpleMetadataSignatureVerificationFilter;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
+
+import org.apache.commons.io.IOUtils;
+import org.joda.time.DateTime;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opensaml.core.config.ConfigurationService;
+import org.opensaml.core.criterion.EntityIdCriterion;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.core.xml.io.MarshallingException;
+import org.opensaml.core.xml.io.UnmarshallingException;
+import org.opensaml.core.xml.util.XMLObjectSupport;
+import org.opensaml.saml.common.xml.SAMLConstants;
+import org.opensaml.saml.criterion.EntityRoleCriterion;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilter;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain;
+import org.opensaml.saml.metadata.resolver.filter.impl.RequiredValidUntilFilter;
+import org.opensaml.saml.metadata.resolver.impl.PredicateRoleDescriptorResolver;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.RequestedAttribute;
+import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.saml.security.impl.MetadataCredentialResolver;
+import org.opensaml.security.credential.Credential;
+import org.opensaml.security.credential.UsageType;
+import org.opensaml.security.criteria.UsageCriterion;
+import org.opensaml.security.x509.BasicX509Credential;
+import org.opensaml.xmlsec.SignatureValidationConfiguration;
+import org.opensaml.xmlsec.SignatureValidationParameters;
+import org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver;
+import org.opensaml.xmlsec.keyinfo.impl.BasicProviderKeyInfoCredentialResolver;
+import org.opensaml.xmlsec.keyinfo.impl.KeyInfoProvider;
+import org.opensaml.xmlsec.keyinfo.impl.provider.DSAKeyValueProvider;
+import org.opensaml.xmlsec.keyinfo.impl.provider.InlineX509DataProvider;
+import org.opensaml.xmlsec.keyinfo.impl.provider.RSAKeyValueProvider;
+import org.opensaml.xmlsec.signature.support.SignatureValidationParametersCriterion;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.w3c.dom.Element;
+
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+import net.shibboleth.utilities.java.support.xml.SerializeSupport;
+import net.shibboleth.utilities.java.support.xml.XMLParserException;
+import okhttp3.HttpUrl;
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration({ "/spring/test_eaaf_pvp.beans.xml" })
+@TestPropertySource(locations = { "/config/config_1.props" })
+public class MetadataResolverTest {
+
+ private static MockWebServer mockWebServer;
+ private static HttpUrl mockServerUrl;
+
+ @Autowired
+ private PvpMetadataResolverFactory metadataResolverFactory;
+ @Autowired
+ private IHttpClientFactory httpClientFactory;
+ @Autowired private DummyCredentialProvider credentialProvider;
+
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void classInitializer() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+ mockWebServer = new MockWebServer();
+ mockServerUrl = mockWebServer.url("/sp/metadata");
+
+ }
+
+ /**
+ * Single test initializer.
+ *
+ */
+ @Before
+ public void testInitializer() {
+
+ }
+
+ @Test
+ public void wrongSchema() {
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ try {
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_wrong_schema.xml",
+ filterChain, "jUnit test", null);
+ Assert.fail("Wrong XML Schema not detected");
+
+ } catch (final Pvp2MetadataException e) {
+ Assert.assertEquals("Wrong ErrorCode", "internal.pvp.08", e.getErrorId());
+ Assert.assertNotNull("params null", e.getParams());
+ Assert.assertEquals("Params size", 2, e.getParams().length);
+ Assert.assertEquals("Param[0] wrong",
+ "classpath:/data/pvp_metadata_wrong_schema.xml", e.getParams()[0]);
+
+ }
+
+ }
+
+ @Test
+ public void simpleClasspathMetadataWithoutSigValidation()
+ throws Pvp2MetadataException, ComponentInitializationException, ResolverException,
+ Pvp2InternalErrorException {
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ final IPvp2MetadataProvider mdResolver = metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_wrong_sig.xml",
+ filterChain, "jUnit test", null);
+
+ final EntityDescriptor entityIdNotExists = mdResolver.getEntityDescriptor(
+ "https://demo.egiz.gv.at/notExtist/");
+ Assert.assertNull("No EntityDescripter", entityIdNotExists);
+
+ final EntityDescriptor entityId = mdResolver.getEntityDescriptor(
+ "https://demo.egiz.gv.at/demoportal_demologin/");
+ Assert.assertNotNull("No EntityDescripter", entityId);
+
+ Assert.assertNotNull("Metadata provider is null", mdResolver);
+ final MetadataCredentialResolver resolver = createKeyInfoResolver(mdResolver);
+
+ final CriteriaSet criteriaSet = new CriteriaSet();
+ criteriaSet.add(new EntityIdCriterion("https://demo.egiz.gv.at/demoportal_demologin/"));
+ criteriaSet.add(new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME));
+ criteriaSet.add(new UsageCriterion(UsageType.SIGNING));
+ final SignatureValidationParameters sigValCrit = new SignatureValidationParameters();
+ sigValCrit.setBlacklistedAlgorithms(
+ ConfigurationService.get(SignatureValidationConfiguration.class)
+ .getBlacklistedAlgorithms());
+ sigValCrit.setSignatureTrustEngine(
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(mdResolver));
+ criteriaSet.add(new SignatureValidationParametersCriterion(sigValCrit));
+
+ final Iterable<Credential> keyInfos = resolver.resolve(criteriaSet);
+ Assert.assertNotNull("KeyInfos null", keyInfos);
+
+ }
+
+ @Test
+ public void noCredentials() {
+ final String metadataUrl = "classpath:/data/pvp_metadata_moaid_test.xml";
+
+ final List<BasicX509Credential> credentials = new ArrayList<>();
+
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+
+ filterList.add(new SimpleMetadataSignatureVerificationFilter(
+ credentials,
+ metadataUrl));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ try {
+ metadataResolverFactory.createMetadataProvider(
+ metadataUrl,
+ filterChain, "jUnit test", null);
+ Assert.fail("Untrusted signature not detected");
+
+ } catch (final Pvp2MetadataException e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.07", e.getErrorId());
+
+ }
+
+ }
+
+ @Test
+ public void wrongCredentials() throws CertificateException {
+ final String metadataUrl = "classpath:/data/pvp_metadata_moaid_test.xml";
+
+ final List<BasicX509Credential> credentials = new ArrayList<>();
+ final CertificateFactory fact = CertificateFactory.getInstance("X.509");
+ final BasicX509Credential credential = new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/assertion_sig_cert.crt")));
+ credentials.add(credential);
+
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+
+ filterList.add(new SimpleMetadataSignatureVerificationFilter(
+ credentials,
+ metadataUrl));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ try {
+ metadataResolverFactory.createMetadataProvider(
+ metadataUrl,
+ filterChain, "jUnit test", null);
+ Assert.fail("Untrusted signature not detected");
+
+ } catch (final Pvp2MetadataException e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.07", e.getErrorId());
+
+ }
+
+ }
+
+ @Test
+ public void validCredentialsInvalidSig() throws CertificateException, Pvp2MetadataException,
+ ResolverException {
+ final String metadataUrl = "classpath:/data/pvp_metadata_moaid_test.xml";
+
+ final List<BasicX509Credential> credentials = new ArrayList<>();
+ final CertificateFactory fact = CertificateFactory.getInstance("X.509");
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/assertion_sig_cert.crt"))));
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/metadata_sig_cert.crt"))));
+
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+
+ filterList.add(new SimpleMetadataSignatureVerificationFilter(
+ credentials,
+ metadataUrl));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+ try {
+ metadataResolverFactory.createMetadataProvider(
+ metadataUrl,
+ filterChain, "jUnit test", null);
+ Assert.fail("Untrusted signature not detected");
+
+ } catch (final Pvp2MetadataException e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.07", e.getErrorId());
+
+ }
+
+ }
+
+ @Test
+ public void metadataSignatureValidCredentials() throws CertificateException, Pvp2MetadataException,
+ ResolverException, XMLParserException, UnmarshallingException, SamlSigningException,
+ CredentialsNotAvailableException, MarshallingException, TransformerException, IOException {
+
+ final String metadataUrl = "classpath:/data/pvp_metadata_valid.xml";
+
+ final List<BasicX509Credential> credentials = new ArrayList<>();
+ final CertificateFactory fact = CertificateFactory.getInstance("X.509");
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/metadata_sig_cert.crt"))));
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/assertion_sig_cert.crt"))));
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/junit_metadata_sig_cert.crt"))));
+
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+ filterList.add(new SimpleMetadataSignatureVerificationFilter(
+ credentials,
+ metadataUrl));
+ filterList.add(new PvpEntityCategoryFilter(true));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ final IPvp2MetadataProvider mdResolver = metadataResolverFactory.createMetadataProvider(
+ metadataUrl,
+ filterChain, "jUnit test", httpClientFactory.getHttpClient());
+
+ final EntityDescriptor entityIdNotExists = mdResolver.getEntityDescriptor(
+ "https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eid/metadata");
+ Assert.assertNotNull("No EntityDescripter", entityIdNotExists);
+
+ }
+
+ @Test
+ public void metadataSignatureValidCredentialsSecond() throws CertificateException, Pvp2MetadataException,
+ ResolverException, XMLParserException, UnmarshallingException, SamlSigningException,
+ CredentialsNotAvailableException, MarshallingException, TransformerException, IOException {
+
+ final EntityDescriptor metadata = (EntityDescriptor) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ MetadataResolverTest.class.getResourceAsStream("/data/pvp_metadata_valid_with_entityCategory.xml"));
+ metadata.setValidUntil(DateTime.now().plusDays(1));
+ metadata.setSignature(null);
+ Saml2Utils.signSamlObject(metadata, credentialProvider.getIdpMetaDataSigningCredential(), true);
+ final Element metadataElement = XMLObjectSupport.marshall(metadata);
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(SerializeSupport.nodeToString(metadataElement))
+ .setHeader("Content-Type", "text/html;charset=utf-8"));
+
+ final List<BasicX509Credential> credentials = new ArrayList<>();
+ final CertificateFactory fact = CertificateFactory.getInstance("X.509");
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/metadata_sig_cert.crt"))));
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/assertion_sig_cert.crt"))));
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/junit_metadata_sig_cert.crt"))));
+
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+ filterList.add(new SimpleMetadataSignatureVerificationFilter(
+ credentials,
+ mockServerUrl.url().toString()));
+ filterList.add(new PvpEntityCategoryFilter(true));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ final IPvp2MetadataProvider mdResolver = metadataResolverFactory.createMetadataProvider(
+ mockServerUrl.url().toString(),
+ filterChain, "jUnit test", httpClientFactory.getHttpClient());
+
+
+
+ final EntityDescriptor descr = mdResolver.getEntityDescriptor(
+ "https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eid/metadata");
+ Assert.assertNotNull("No EntityDescripter", descr);
+
+ final List<RequestedAttribute> reqAttr = descr.getSPSSODescriptor(SAMLConstants.SAML20P_NS)
+ .getAttributeConsumingServices().get(0).getRequestAttributes();
+ Assert.assertNotNull("Req. attributes are null", reqAttr);
+ Assert.assertEquals("# of req. attributes", 20, reqAttr.size());
+
+ }
+
+ @Test
+ public void metadataSignatureValidCredentialsThird() throws CertificateException, Pvp2MetadataException,
+ ResolverException, XMLParserException, UnmarshallingException, SamlSigningException,
+ CredentialsNotAvailableException, MarshallingException, TransformerException, IOException {
+
+ final EntityDescriptor metadata = (EntityDescriptor) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ MetadataResolverTest.class.getResourceAsStream("/data/pvp_metadata_valid_with_entityCategory_egov.xml"));
+ metadata.setValidUntil(DateTime.now().plusDays(1));
+ metadata.setSignature(null);
+ Saml2Utils.signSamlObject(metadata, credentialProvider.getIdpMetaDataSigningCredential(), true);
+ final Element metadataElement = XMLObjectSupport.marshall(metadata);
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(SerializeSupport.nodeToString(metadataElement))
+ .setHeader("Content-Type", "text/html;charset=utf-8"));
+
+ final List<BasicX509Credential> credentials = new ArrayList<>();
+ final CertificateFactory fact = CertificateFactory.getInstance("X.509");
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/metadata_sig_cert.crt"))));
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/assertion_sig_cert.crt"))));
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/junit_metadata_sig_cert.crt"))));
+
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+ filterList.add(new SimpleMetadataSignatureVerificationFilter(
+ credentials,
+ mockServerUrl.url().toString()));
+ filterList.add(new PvpEntityCategoryFilter(true));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ final IPvp2MetadataProvider mdResolver = metadataResolverFactory.createMetadataProvider(
+ mockServerUrl.url().toString(),
+ filterChain, "jUnit test", httpClientFactory.getHttpClient());
+
+
+
+ final EntityDescriptor descr = mdResolver.getEntityDescriptor(
+ "https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eid/metadata");
+ Assert.assertNotNull("No EntityDescripter", descr);
+
+ final List<RequestedAttribute> reqAttr = descr.getSPSSODescriptor(SAMLConstants.SAML20P_NS)
+ .getAttributeConsumingServices().get(0).getRequestAttributes();
+ Assert.assertNotNull("Req. attributes are null", reqAttr);
+ Assert.assertEquals("# of req. attributes", 9, reqAttr.size());
+
+ }
+
+ @Test
+ public void metadataExpired() throws CertificateException, Pvp2MetadataException,
+ ResolverException, XMLParserException, UnmarshallingException, SamlSigningException,
+ CredentialsNotAvailableException, MarshallingException, TransformerException, IOException {
+
+ final EntityDescriptor metadata = (EntityDescriptor) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ MetadataResolverTest.class.getResourceAsStream("/data/pvp_metadata_valid.xml"));
+ metadata.setValidUntil(DateTime.now().minusDays(2));
+ metadata.setSignature(null);
+ Saml2Utils.signSamlObject(metadata, credentialProvider.getIdpMetaDataSigningCredential(), true);
+ final Element metadataElement = XMLObjectSupport.marshall(metadata);
+
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(SerializeSupport.nodeToString(metadataElement))
+ .setHeader("Content-Type", "text/html;charset=utf-8"));
+
+ final List<BasicX509Credential> credentials = new ArrayList<>();
+ final CertificateFactory fact = CertificateFactory.getInstance("X.509");
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/metadata_sig_cert.crt"))));
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/assertion_sig_cert.crt"))));
+ credentials.add(new BasicX509Credential((X509Certificate) fact.generateCertificate(
+ MetadataResolverTest.class.getResourceAsStream("/data/junit_metadata_sig_cert.crt"))));
+
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+ filterList.add(new SimpleMetadataSignatureVerificationFilter(
+ credentials,
+ mockServerUrl.url().toString()));
+ filterList.add(new RequiredValidUntilFilter());
+ filterList.add(new PvpEntityCategoryFilter(false));
+
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ try {
+ metadataResolverFactory.createMetadataProvider(
+ mockServerUrl.url().toString(),
+ filterChain, "jUnit test", httpClientFactory.getHttpClient());
+ Assert.fail("Expired metadata not detected");
+
+ } catch (final Pvp2MetadataException e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.09", e.getErrorId());
+
+ }
+
+
+ }
+
+ @Test
+ public void simpleClasspathMetadataWithoutSigValidationMoaidTwoSigKeys()
+ throws Pvp2MetadataException, ComponentInitializationException, ResolverException,
+ Pvp2InternalErrorException {
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ final String entityIdToResolve = "https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/metadata";
+
+ final IPvp2MetadataProvider mdResolver = metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_moaid_test.xml",
+ filterChain, "jUnit test", null);
+
+ final EntityDescriptor entityIdNotExists = mdResolver.getEntityDescriptor(
+ "https://demo.egiz.gv.at/notExtist/");
+ Assert.assertNull("No EntityDescripter", entityIdNotExists);
+
+ final EntityDescriptor entityId = mdResolver.getEntityDescriptor(entityIdToResolve);
+ Assert.assertNotNull("No EntityDescripter", entityId);
+
+ Assert.assertNotNull("Metadata provider is null", mdResolver);
+ final MetadataCredentialResolver resolver = createKeyInfoResolver(mdResolver);
+
+ final CriteriaSet sigCriteriaSet = new CriteriaSet();
+ sigCriteriaSet.add(new EntityIdCriterion(entityIdToResolve));
+ sigCriteriaSet.add(new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME));
+ sigCriteriaSet.add(new UsageCriterion(UsageType.SIGNING));
+ final SignatureValidationParameters sigValCrit = new SignatureValidationParameters();
+ sigValCrit.setBlacklistedAlgorithms(
+ ConfigurationService.get(SignatureValidationConfiguration.class)
+ .getBlacklistedAlgorithms());
+ sigValCrit.setSignatureTrustEngine(
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(mdResolver));
+ sigCriteriaSet.add(new SignatureValidationParametersCriterion(sigValCrit));
+
+ final Iterable<Credential> singingKeyInfos = resolver.resolve(sigCriteriaSet);
+ Assert.assertNotNull("Signing KeyInfos null", singingKeyInfos);
+ Assert.assertTrue("First Credential resolved", singingKeyInfos.iterator().hasNext());
+ Assert.assertTrue("Second Credential resolved", singingKeyInfos.iterator().hasNext());
+
+ final CriteriaSet encCriteriaSet = new CriteriaSet();
+ encCriteriaSet.add(new EntityIdCriterion(entityIdToResolve));
+ encCriteriaSet.add(new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME));
+ encCriteriaSet.add(new UsageCriterion(UsageType.ENCRYPTION));
+ final Iterable<Credential> encKeyInfos = resolver.resolve(encCriteriaSet);
+ Assert.assertNotNull("Encryption KeyInfos null", encKeyInfos);
+ Assert.assertTrue("No Credential resolved", encKeyInfos.iterator().hasNext());
+
+ }
+
+ @Test
+ public void httpMetadataLoading() throws UnsupportedEncodingException,
+ IOException, ResolverException, Pvp2MetadataException {
+
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(new String(IOUtils.toByteArray(
+ MetadataResolverTest.class.getResourceAsStream(
+ "/data/pvp_metadata_moaid_test.xml")), "UTF-8"))
+ .setHeader("Content-Type", "text/xml"));
+
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ final String entityIdToResolve = "https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/metadata";
+
+ final IPvp2MetadataProvider mdResolver = metadataResolverFactory.createMetadataProvider(
+ mockServerUrl.url().toString(),
+ filterChain, "jUnit test", httpClientFactory.getHttpClient());
+
+ final EntityDescriptor entityIdNotExists = mdResolver.getEntityDescriptor(
+ "https://demo.egiz.gv.at/notExtist/");
+ Assert.assertNull("No EntityDescripter", entityIdNotExists);
+
+ final EntityDescriptor entityId = mdResolver.getEntityDescriptor(entityIdToResolve);
+ Assert.assertNotNull("No EntityDescripter", entityId);
+
+ }
+
+ @Test
+ public void httpMetadataLoadingRefeshFailed() throws UnsupportedEncodingException,
+ IOException, ResolverException, Pvp2MetadataException {
+
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(new String(IOUtils.toByteArray(
+ MetadataResolverTest.class.getResourceAsStream(
+ "/data/pvp_metadata_moaid_test.xml")), "UTF-8"))
+ .setHeader("Content-Type", "text/xml"));
+
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ final String entityIdToResolve = "https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/metadata";
+
+ final IPvp2MetadataProvider mdResolver = metadataResolverFactory.createMetadataProvider(
+ mockServerUrl.url().toString(),
+ filterChain, "jUnit test", httpClientFactory.getHttpClient());
+
+ final EntityDescriptor entityIdNotExists = mdResolver.getEntityDescriptor(
+ "https://demo.egiz.gv.at/notExtist/");
+ Assert.assertNull("No EntityDescripter", entityIdNotExists);
+
+ final EntityDescriptor entityId = mdResolver.getEntityDescriptor(entityIdToResolve);
+ Assert.assertNotNull("No EntityDescripter", entityId);
+
+ final DateTime lastRefreshSucess = mdResolver.getLastSuccessfulRefresh();
+
+ try {
+ mdResolver.refresh();
+ Assert.fail("Refesh possible without available metadata");
+
+ } catch (final ResolverException e) {
+ Assert.assertFalse("Wrong Refesh success flag", mdResolver.wasLastRefreshSuccess());
+ Assert.assertEquals("Wrong refresh success date", lastRefreshSucess, mdResolver
+ .getLastSuccessfulRefresh());
+
+ }
+
+ }
+
+ @Test
+ public void httpMetadataLoadingWithRefeshSuccess() throws UnsupportedEncodingException,
+ IOException, ResolverException, Pvp2MetadataException {
+
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(new String(IOUtils.toByteArray(
+ MetadataResolverTest.class.getResourceAsStream(
+ "/data/pvp_metadata_moaid_test.xml")), "UTF-8"))
+ .setHeader("Content-Type", "text/xml"));
+
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(new String(IOUtils.toByteArray(
+ MetadataResolverTest.class.getResourceAsStream(
+ "/data/pvp_metadata_moaid_test.xml")), "UTF-8"))
+ .setHeader("Content-Type", "text/xml"));
+
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ final String entityIdToResolve = "https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/metadata";
+
+ final IPvp2MetadataProvider mdResolver = metadataResolverFactory.createMetadataProvider(
+ mockServerUrl.url().toString(),
+ filterChain, "jUnit test", httpClientFactory.getHttpClient());
+
+ final EntityDescriptor entityIdNotExists = mdResolver.getEntityDescriptor(
+ "https://demo.egiz.gv.at/notExtist/");
+ Assert.assertNull("No EntityDescripter", entityIdNotExists);
+
+ final EntityDescriptor entityId = mdResolver.getEntityDescriptor(entityIdToResolve);
+ Assert.assertNotNull("No EntityDescripter", entityId);
+
+ final DateTime lastRefresh = mdResolver.getLastRefresh();
+
+ // refresh metadata
+ mdResolver.refresh();
+
+ Assert.assertTrue("Refresh not sucessful", mdResolver.wasLastRefreshSuccess());
+ Assert.assertTrue("Wrong last refresh date", lastRefresh.isBefore(mdResolver.getLastRefresh()));
+
+ }
+
+ @Test
+ public void httpMetadataLoadingWithoutHttpClient() throws UnsupportedEncodingException,
+ IOException, ResolverException, Pvp2MetadataException {
+
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(new String(IOUtils.toByteArray(
+ MetadataResolverTest.class.getResourceAsStream(
+ "/data/pvp_metadata_moaid_test.xml")), "UTF-8"))
+ .setHeader("Content-Type", "text/xml"));
+
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ try {
+ metadataResolverFactory.createMetadataProvider(
+ mockServerUrl.url().toString(),
+ filterChain, "jUnit test", null);
+ Assert.fail("No httpclient not detected");
+
+ } catch (final Pvp2MetadataException e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.09", e.getErrorId());
+ Assert.assertNotNull("No error params", e.getParams());
+ Assert.assertEquals("Wrong params size", 2, e.getParams().length);
+
+ }
+ }
+
+ @Test
+ public void httpMetadataLoadingWrongUrl() throws UnsupportedEncodingException,
+ IOException, ResolverException, Pvp2MetadataException {
+
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(new String(IOUtils.toByteArray(
+ MetadataResolverTest.class.getResourceAsStream(
+ "/data/pvp_metadata_moaid_test.xml")), "UTF-8"))
+ .setHeader("Content-Type", "text/xml"));
+
+ final List<MetadataFilter> filterList = new ArrayList<>();
+ filterList.add(new SchemaValidationFilter(true));
+
+ final MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.setFilters(filterList);
+
+ try {
+ metadataResolverFactory.createMetadataProvider(
+ "http://127.0.0.1/notexist",
+ filterChain, "jUnit test", httpClientFactory.getHttpClient());
+ Assert.fail("No httpclient not detected");
+
+ } catch (final Pvp2MetadataException e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.09", e.getErrorId());
+ Assert.assertNotNull("No error params", e.getParams());
+ Assert.assertEquals("Wrong params size", 2, e.getParams().length);
+
+ }
+
+ }
+
+ private MetadataCredentialResolver createKeyInfoResolver(IPvp2MetadataProvider mdResolver)
+ throws ComponentInitializationException {
+ final List<KeyInfoProvider> keyInfoProvider = new ArrayList<>();
+ keyInfoProvider.add(new DSAKeyValueProvider());
+ keyInfoProvider.add(new RSAKeyValueProvider());
+ keyInfoProvider.add(new InlineX509DataProvider());
+ final KeyInfoCredentialResolver keyInfoCredentialResolver = new BasicProviderKeyInfoCredentialResolver(
+ keyInfoProvider);
+
+ final PredicateRoleDescriptorResolver roleDescriptorResolver = new PredicateRoleDescriptorResolver(
+ mdResolver);
+ roleDescriptorResolver.setRequireValidMetadata(true);
+ roleDescriptorResolver.initialize();
+
+ final MetadataCredentialResolver resolver = new MetadataCredentialResolver();
+ resolver.setRoleDescriptorResolver(roleDescriptorResolver);
+ resolver.setKeyInfoCredentialResolver(keyInfoCredentialResolver);
+ resolver.initialize();
+
+ return resolver;
+ }
+}