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; import javax.xml.parsers.ParserConfigurationException; 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.xml.XMLObject; import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport; import org.opensaml.core.xml.io.MarshallingException; import org.opensaml.core.xml.io.Unmarshaller; import org.opensaml.core.xml.io.UnmarshallerFactory; import org.opensaml.core.xml.io.UnmarshallingException; import org.opensaml.core.xml.schema.XSString; import org.opensaml.core.xml.util.XMLObjectSupport; import org.opensaml.messaging.decoder.MessageDecodingException; import org.opensaml.messaging.encoder.MessageEncodingException; import org.opensaml.saml.common.SignableSAMLObject; import org.opensaml.saml.saml2.core.AuthnRequest; import org.opensaml.saml.saml2.core.Issuer; 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; 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 org.xml.sax.SAXException; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiBuilderConfiguration; import at.gv.egiz.eaaf.core.impl.http.IHttpClientFactory; 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.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.api.reqattr.EaafRequestedAttribute; import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes; 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.message.InboundMessage; import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileRequest; import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileResponse; 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 at.gv.egiz.eaaf.modules.pvp2.test.metadata.MetadataResolverTest; import net.shibboleth.utilities.java.support.net.URIComparator; 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", "/spring/test_eaaf_core_spring_config.beans.xml", "/spring/eaaf_utils.beans.xml"}) @TestPropertySource(locations = {"/config/config_1.props"}) public class PostBindingTest { public static final String HTTP_FORM_RELAYSTATE = "RelayState="; public static final String HTTP_FORM_SAMLREQ = "SAMLRequest="; public static final String HTTP_FORM_SAMLRESP = "SAMLResponse="; @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 Exception { EaafOpenSaml3xInitializer.eaafInitialize(); mockWebServer = new MockWebServer(); mockServerUrl = mockWebServer.url("/sp/metadata"); } /** * Test initializer. * */ @Before public void initialize() { httpReq = new MockHttpServletRequest(); httpResp = new MockHttpServletResponse(); pendingReq = new TestRequestImpl(); } @Test public void checkCanHandle() { httpReq.setMethod("POST"); Assert.assertTrue("Wrong canHandle result", bindingImpl.handleDecode("Post", httpReq)); Assert.assertFalse("Wrong canHandle result", bindingImpl.handleDecode("Redirect", httpReq)); httpReq.setMethod("GET"); Assert.assertFalse("Wrong canHandle result", bindingImpl.handleDecode("Post", httpReq)); Assert.assertFalse("Wrong canHandle result", bindingImpl.handleDecode("Redirect", httpReq)); } @Test public void wrongPostBindingEncoding() 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); httpReq.setParameter("SAMLEncoding", RandomStringUtils.randomAlphabetic(5)); 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, Pvp2MetadataException { final String serviceUrl = "https://wrongEndpoint/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("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.getMetaDataSigningCredential()); 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, SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator); Assert.assertNotNull("PVP msg is null", msg); 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.assertTrue("Wrong isVerified flag", msg.isVerified()); } @Test 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 = generateSaml2AuthnRequest( credentialProvider.getMetaDataSigningCredential()); 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 URIComparator comparator = new EaafUriCompare(serviceUrl); final InboundMessageInterface msg = 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.assertTrue("Wrong isVerified flag", msg.isVerified()); } @Test public void decodeRequestSuccessWithRequestAttributes() throws MessageDecodingException, SecurityException, IOException, Pvp2Exception, CredentialsNotAvailableException, XMLParserException, UnmarshallingException, MarshallingException { final String serviceUrl = "https://eidas-test.bmi.gv.at/ms_connector/pvp/post"; final String relayState = RandomStringUtils.randomAlphanumeric(10); final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream( XMLObjectProviderRegistrySupport.getParserPool(), PostBindingTest.class.getResourceAsStream("/data/eIDAS_connector_authn.xml")); authnReq.setIssueInstant(DateTime.now()); final Issuer issuer = Saml2Utils.createSamlObject(Issuer.class); issuer.setValue("https://demo.egiz.gv.at/demoportal_demologin/"); authnReq.setIssuer(issuer); final RequestAbstractType signedAuthn = Saml2Utils.signSamlObject( authnReq, credentialProvider.getMessageSigningCredential(), true); final Element signedElement = XMLObjectSupport.getMarshaller(signedAuthn).marshall(signedAuthn); final String b64AuthnReq = Base64.getEncoder().encodeToString(SerializeSupport.nodeToString(signedElement).getBytes("UTF-8")); 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 URIComparator comparator = new EaafUriCompare(serviceUrl); final InboundMessageInterface msg = 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.assertTrue("Wrong isVerified flag", msg.isVerified()); org.springframework.util.Assert.isInstanceOf(PvpSProfileRequest.class, msg, "Inbound message is of wrong type"); org.springframework.util.Assert.isInstanceOf(AuthnRequest.class, ((PvpSProfileRequest)msg).getSamlRequest(), "Inbound message is of wrong type"); final AuthnRequest parsedAuthnReq = (AuthnRequest)((PvpSProfileRequest)msg).getSamlRequest(); Assert.assertNotNull("No extension", parsedAuthnReq.getExtensions()); Assert.assertNotNull("No extension child", parsedAuthnReq.getExtensions().getUnknownXMLObjects()); Assert.assertEquals("extension child size", 1, parsedAuthnReq.getExtensions().getUnknownXMLObjects().size()); final XMLObject reqAttrs = parsedAuthnReq.getExtensions().getUnknownXMLObjects().get(0); org.springframework.util.Assert.isInstanceOf( EaafRequestedAttributes.class, reqAttrs, "Wrong requested Attributes type"); final EaafRequestedAttributes eaafReqAttrs = (EaafRequestedAttributes) reqAttrs; Assert.assertNotNull("Req attr is null", eaafReqAttrs.getAttributes()); Assert.assertFalse("Req attr is empty", eaafReqAttrs.getAttributes().isEmpty()); Assert.assertEquals("Req attr size", 1, eaafReqAttrs.getAttributes().size()); final EaafRequestedAttribute eaafReqAttr = eaafReqAttrs.getAttributes().get(0); Assert.assertNotNull("Req Attibute is null", eaafReqAttr); Assert.assertEquals("Req. Attr. Friendlyname", "EID-SECTOR-FOR-IDENTIFIER", eaafReqAttr.getFriendlyName()); Assert.assertEquals("Req. Attr. Name", "urn:oid:1.2.40.0.10.2.1.1.261.34", eaafReqAttr.getName()); Assert.assertEquals("Req. Attr. Value size", 1, eaafReqAttr.getAttributeValues().size()); org.springframework.util.Assert.isInstanceOf(XSString.class, eaafReqAttr.getAttributeValues().get(0), "Wrong requested Attributes Value type"); Assert.assertEquals("Req. Attr. Value", "urn:publicid:gv.at:cdid+BF", ((XSString)eaafReqAttr.getAttributeValues().get(0)).getValue()); } @Test public void decodeRequestSuccessWithoutRelayStateEcdsaSig() throws MessageDecodingException, SecurityException, IOException, Pvp2Exception, CredentialsNotAvailableException, XMLParserException, UnmarshallingException { final String serviceUrl = "http://testservice.org"; final String b64AuthnReq = generateSaml2AuthnRequest( credentialProvider.getMessageSigningCredential()); 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, 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.assertTrue("Wrong isVerified flag", msg.isVerified()); //check if reconstraction from serialized form work well ((InboundMessage)msg).setSamlMessage(null); try { Assert.assertNotNull("AuthnReq is null", msg.getInboundMessage()); } catch (final RuntimeException e) { Assert.assertNotNull("No errorMsg", e.getMessage()); } } @Test public void decodeResponseSuccess() 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); final String b64AuthnReq = generateSaml2Response(credentialProvider.getMetaDataSigningCredential()); httpReq.setMethod("POST"); httpReq.addParameter("SAMLRequest", b64AuthnReq); final InboundMessageInterface msg = 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_demologin/", msg.getEntityID()); Assert.assertTrue("Wrong isVerified flag", msg.isVerified()); org.springframework.util.Assert.isInstanceOf(PvpSProfileResponse.class, msg, "Inbound message is of wrong type"); } @Test public void encodeRequestSuccess() throws MessageDecodingException, SecurityException, MessageEncodingException, XMLParserException, UnmarshallingException, CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException, Pvp2Exception { //build test data final String serviceUrl = "http://testservice.org"; final String relayState = null; guiBuilderFactory.setVelocityBuilderConfig(createDummyGuiConfig()); final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream( XMLObjectProviderRegistrySupport.getParserPool(), PostBindingTest.class.getResourceAsStream("/data/AuthRequest_without_sig_1.xml")); bindingImpl.encodeRequest(httpReq, httpResp, authnReq, serviceUrl, relayState, credentialProvider.getMetaDataSigningCredential(), pendingReq); //validate Assert.assertEquals("http StatusCode", 200, httpResp.getStatus()); Assert.assertNotNull("PVP msg is null", httpResp.getContentLength()); Assert.assertEquals("ContentType", "text/html", 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()); Assert.assertFalse("RelayState parameter", http.contains(HTTP_FORM_RELAYSTATE)); Assert.assertTrue("SAMLRequest parameter", http.contains(HTTP_FORM_SAMLREQ)); final String httpSamlReq = extractParamFromHttpForm(http, HTTP_FORM_SAMLREQ); checkSamlMessageSigned(httpSamlReq); } @Test public void encodeRequestSuccessEcdsa() throws MessageDecodingException, SecurityException, MessageEncodingException, XMLParserException, UnmarshallingException, CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException, Pvp2Exception { //build test data final String serviceUrl = "http://testservice.org"; final String relayState = null; guiBuilderFactory.setVelocityBuilderConfig(createDummyGuiConfig()); final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream( XMLObjectProviderRegistrySupport.getParserPool(), PostBindingTest.class.getResourceAsStream("/data/AuthRequest_without_sig_1.xml")); bindingImpl.encodeRequest(httpReq, httpResp, authnReq, serviceUrl, relayState, credentialProvider.getMessageSigningCredential(), pendingReq); //validate Assert.assertEquals("http StatusCode", 200, httpResp.getStatus()); Assert.assertNotNull("PVP msg is null", httpResp.getContentLength()); Assert.assertEquals("ContentType", "text/html", 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()); Assert.assertFalse("RelayState parameter", http.contains(HTTP_FORM_RELAYSTATE)); Assert.assertTrue("SAMLRequest parameter", http.contains(HTTP_FORM_SAMLREQ)); final String httpSamlReq = extractParamFromHttpForm(http, HTTP_FORM_SAMLREQ); checkSamlMessageSigned(httpSamlReq); } @Test public void encodeRequestSuccessWithRelayState() throws MessageDecodingException, SecurityException, MessageEncodingException, XMLParserException, UnmarshallingException, CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException, Pvp2Exception { //build test data final String serviceUrl = "http://testservice.org"; final String relayState = RandomStringUtils.randomAlphabetic(10); guiBuilderFactory.setVelocityBuilderConfig(createDummyGuiConfig()); final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream( XMLObjectProviderRegistrySupport.getParserPool(), PostBindingTest.class.getResourceAsStream("/data/AuthRequest_without_sig_1.xml")); bindingImpl.encodeRequest(httpReq, httpResp, authnReq, serviceUrl, relayState, credentialProvider.getMetaDataSigningCredential(), pendingReq); //validate Assert.assertEquals("http StatusCode", 200, httpResp.getStatus()); Assert.assertNotNull("PVP msg is null", httpResp.getContentLength()); Assert.assertEquals("ContentType", "text/html", 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()); Assert.assertTrue("RelayState parameter", http.contains(HTTP_FORM_RELAYSTATE)); final String httpRelayState = extractParamFromHttpForm(http, HTTP_FORM_RELAYSTATE); Assert.assertEquals("Wrong RelayState", relayState, httpRelayState); Assert.assertTrue("SAMLRequest parameter", http.contains(HTTP_FORM_SAMLREQ)); final String httpSamlReq = extractParamFromHttpForm(http, HTTP_FORM_SAMLREQ); checkSamlMessageSigned(httpSamlReq); } @Test public void encodeResponseSuccessWithRelayState() throws MessageDecodingException, SecurityException, MessageEncodingException, XMLParserException, UnmarshallingException, CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException, Pvp2Exception { //build test data final String serviceUrl = "http://testservice.org"; final String relayState = RandomStringUtils.randomAlphabetic(10); guiBuilderFactory.setVelocityBuilderConfig(createDummyGuiConfig()); final StatusResponseType authnReq = (StatusResponseType) XMLObjectSupport.unmarshallFromInputStream( XMLObjectProviderRegistrySupport.getParserPool(), PostBindingTest.class.getResourceAsStream("/data/Response_without_sig_1.xml")); bindingImpl.encodeResponse(httpReq, httpResp, authnReq, serviceUrl, relayState, credentialProvider.getMetaDataSigningCredential(), pendingReq); //validate Assert.assertEquals("http StatusCode", 200, httpResp.getStatus()); Assert.assertNotNull("PVP msg is null", httpResp.getContentLength()); Assert.assertEquals("ContentType", "text/html", 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()); Assert.assertTrue("RelayState parameter", http.contains(HTTP_FORM_RELAYSTATE)); final String httpRelayState = extractParamFromHttpForm(http, HTTP_FORM_RELAYSTATE); Assert.assertEquals("Wrong RelayState", relayState, httpRelayState); Assert.assertTrue("SAMLRequest parameter", http.contains(HTTP_FORM_SAMLRESP)); final String httpSamlReq = extractParamFromHttpForm(http, HTTP_FORM_SAMLRESP); checkSamlMessageSigned(httpSamlReq); } @Test public void encodeResponseSuccess() throws MessageDecodingException, SecurityException, MessageEncodingException, XMLParserException, UnmarshallingException, CredentialsNotAvailableException, ParserConfigurationException, SAXException, IOException, Pvp2Exception { //build test data final String serviceUrl = "http://testservice.org"; final String relayState = null; guiBuilderFactory.setVelocityBuilderConfig(createDummyGuiConfig()); final StatusResponseType authnReq = (StatusResponseType) XMLObjectSupport.unmarshallFromInputStream( XMLObjectProviderRegistrySupport.getParserPool(), PostBindingTest.class.getResourceAsStream("/data/Response_without_sig_1.xml")); bindingImpl.encodeResponse(httpReq, httpResp, authnReq, serviceUrl, relayState, credentialProvider.getMetaDataSigningCredential(), pendingReq); //validate Assert.assertEquals("http StatusCode", 200, httpResp.getStatus()); Assert.assertNotNull("PVP msg is null", httpResp.getContentLength()); Assert.assertEquals("ContentType", "text/html", 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()); Assert.assertFalse("RelayState parameter", http.contains(HTTP_FORM_RELAYSTATE)); Assert.assertTrue("SAMLRequest parameter", http.contains(HTTP_FORM_SAMLRESP)); final String httpSamlReq = extractParamFromHttpForm(http, HTTP_FORM_SAMLRESP); checkSamlMessageSigned(httpSamlReq); } private IVelocityGuiBuilderConfiguration createDummyGuiConfig() { return new IVelocityGuiBuilderConfiguration() { @Override public Map getViewParameters() { return null; } @Override public String getViewName() { return "SAML2 Post-Binding"; } @Override public String getDefaultContentType() { return null; } @Override public InputStream getTemplate(String viewName) { return PostBindingTest.class.getResourceAsStream("/data/pvp_postbinding_template.html"); } @Override public String getClasspathTemplateDir() { return null; } }; } private void checkSamlMessageSigned(String b64Msg) throws ParserConfigurationException, SAXException, IOException, UnmarshallingException { final Element httpSamlReqElment = DomUtils.parseXmlNonValidating( new ByteArrayInputStream(Base64.getDecoder().decode(b64Msg))); final UnmarshallerFactory unmarshallerFactory = XMLObjectProviderRegistrySupport.getUnmarshallerFactory(); final Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(httpSamlReqElment); final SignableSAMLObject msg = (SignableSAMLObject) unmarshaller.unmarshall(httpSamlReqElment); Assert.assertTrue("SAML msg not signed", msg.isSigned()); } private String extractParamFromHttpForm(String http, String httpFormRelaystate) { final int startIndex = http.indexOf(httpFormRelaystate) + httpFormRelaystate.length(); final int endIndex = http.indexOf("\"", startIndex); return http.substring(startIndex, endIndex); } 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); } }