diff options
author | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2020-02-04 17:37:34 +0100 |
---|---|---|
committer | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2020-02-04 17:37:34 +0100 |
commit | e7610325ee2f1d1f4e97e1e7a9b212e692836b5a (patch) | |
tree | ed7c0dba5fed47e80e68b4ab5a63846c5724a8e7 /eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding | |
parent | 41ea2fdf782cd64d7d29f73c2e83f9c255810818 (diff) | |
download | EAAF-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/modules/pvp2/test/binding')
3 files changed, 878 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()); + + } + +} |