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", "/spring/test_eaaf_core_spring_config.beans.xml", "/spring/eaaf_utils.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.getMetaDataSigningCredential(), 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.getMetaDataSigningCredential(), 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()); } }