aboutsummaryrefslogtreecommitdiff
path: root/ms_specific_proxyservice/src/test
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2022-08-17 10:51:54 +0000
committerThomas Lenz <thomas.lenz@egiz.gv.at>2022-08-17 10:51:54 +0000
commitd83cf36c1454a10f5a46d677b5f0f30e0cbe7e95 (patch)
tree1cf2bf2853d604d8579cc3f5bf411d10f80c0207 /ms_specific_proxyservice/src/test
parent48f19dc45cec670fe62399d09fb34732fb4eeedc (diff)
parent920d33465e5ab1a71d81cc280e41de10cd8b5247 (diff)
downloadNational_eIDAS_Gateway-d83cf36c1454a10f5a46d677b5f0f30e0cbe7e95.tar.gz
National_eIDAS_Gateway-d83cf36c1454a10f5a46d677b5f0f30e0cbe7e95.tar.bz2
National_eIDAS_Gateway-d83cf36c1454a10f5a46d677b5f0f30e0cbe7e95.zip
Merge branch 'feature/ms_proxy_service' into 'nightlybuild'
add basic implementation of eIDAS-Node Proxy-Service request-controller See merge request egiz/eidas_at_proxy!20
Diffstat (limited to 'ms_specific_proxyservice/src/test')
-rw-r--r--ms_specific_proxyservice/src/test/java/at/asitplus/eidas/specific/proxy/test/FullStartUpAndProcessTest.java480
-rw-r--r--ms_specific_proxyservice/src/test/java/at/asitplus/eidas/specific/proxy/test/MsConnectorSpringResourceProviderTest.java56
-rw-r--r--ms_specific_proxyservice/src/test/java/at/asitplus/eidas/specific/proxy/test/builder/ProxyAuthenticationDataBuilderTest.java395
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/eIDAS/additional-attributes.xml39
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/eIDAS/eidas-attributes.xml376
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/eIDAS/igniteSpecificCommunication.xml109
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/eIDAS/specificCommunicationDefinitionConnector.xml37
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/eIDAS/specificCommunicationDefinitionProxyservice.xml37
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/junit_config_1_springboot.properties123
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/keys/Metadata.pem18
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/keys/junit.jksbin0 -> 3980 bytes
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/keys/junit_test.jksbin0 -> 8410 bytes
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/keys/teststore.jksbin0 -> 2028 bytes
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/logback_config.xml102
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/properties/messages.properties0
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/properties/messages_de.properties0
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/properties/messages_en.properties0
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/templates/eidas_node_forward.html36
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/templates/error.html53
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/templates/error_message.html37
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/templates/pvp2_post_binding.html36
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/webcontent/autocommit.js5
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/webcontent/css/css_error.css26
-rw-r--r--ms_specific_proxyservice/src/test/resources/config/webcontent/img/ajax-loader.gifbin0 -> 673 bytes
-rw-r--r--ms_specific_proxyservice/src/test/resources/data/Response_with_EID.xml49
-rw-r--r--ms_specific_proxyservice/src/test/resources/data/idp_metadata_classpath_entity.xml146
26 files changed, 2160 insertions, 0 deletions
diff --git a/ms_specific_proxyservice/src/test/java/at/asitplus/eidas/specific/proxy/test/FullStartUpAndProcessTest.java b/ms_specific_proxyservice/src/test/java/at/asitplus/eidas/specific/proxy/test/FullStartUpAndProcessTest.java
new file mode 100644
index 00000000..2fe7ee05
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/java/at/asitplus/eidas/specific/proxy/test/FullStartUpAndProcessTest.java
@@ -0,0 +1,480 @@
+package at.asitplus.eidas.specific.proxy.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.util.Base64;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.Timer;
+import java.util.UUID;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.ignite.Ignition;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.junit.AfterClass;
+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.UnmarshallingException;
+import org.opensaml.core.xml.util.XMLObjectSupport;
+import org.opensaml.saml.metadata.resolver.impl.ResourceBackedMetadataResolver;
+import org.opensaml.saml.saml2.core.Issuer;
+import org.opensaml.saml.saml2.core.RequestAbstractType;
+import org.opensaml.saml.saml2.core.Response;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.annotation.DirtiesContext.ClassMode;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.util.Base64Utils;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import com.google.common.collect.ImmutableSet;
+
+import at.asitplus.eidas.specific.modules.auth.idaustria.controller.IdAustriaAuthSignalController;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthCredentialProvider;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthMetadataProvider;
+import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
+import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
+import at.asitplus.eidas.specific.modules.msproxyservice.protocol.EidasProxyServiceController;
+import at.gv.egiz.components.spring.api.SpringBootApplicationContextInitializer;
+import at.gv.egiz.eaaf.core.api.IStatusMessenger;
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.impl.idp.controller.ProtocolFinalizationController;
+import at.gv.egiz.eaaf.core.impl.logging.LogMessageProviderFactory;
+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.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.OpenSaml3ResourceAdapter;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+import eu.eidas.auth.cache.IgniteInstanceInitializerSpecificCommunication;
+import eu.eidas.auth.commons.EidasParameterKeys;
+import eu.eidas.auth.commons.attribute.AttributeValue;
+import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
+import eu.eidas.auth.commons.light.ILightResponse;
+import eu.eidas.auth.commons.light.impl.LightRequest;
+import eu.eidas.auth.commons.tx.BinaryLightToken;
+import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames;
+import eu.eidas.specificcommunication.protocol.SpecificCommunicationService;
+import lombok.SneakyThrows;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.xml.XMLParserException;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest
+@ContextConfiguration(initializers = {
+ org.springframework.boot.context.config.DelegatingApplicationContextInitializer.class,
+ SpringBootApplicationContextInitializer.class
+ })
+@TestPropertySource(locations = { "file:src/test/resources/config/junit_config_1_springboot.properties" })
+@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
+@ActiveProfiles(profiles = {"JUNIT", "jUnitTestMode"})
+public class FullStartUpAndProcessTest {
+
+ private static final String METADATA_PATH = "classpath:/data/idp_metadata_classpath_entity.xml";
+ private static final String FINAL_REDIRECT = "https://localhost/ms_proxy/public/secure/finalizeAuthProtocol?pendingid=";
+ private static final String ERROR_REDIRECT = "https://localhost/ms_proxy/public/secure/errorHandling?errorid=";
+
+
+ @Autowired private WebApplicationContext wac;
+
+ @Autowired private ResourceLoader resourceLoader;
+ @Autowired private EidasAttributeRegistry attrRegistry;
+
+ @Autowired private IdAustriaAuthSignalController idAustriaEndpoint;
+ @Autowired private IdAustriaAuthMetadataProvider idAustriaMetadata;
+ @Autowired private IdAustriaAuthCredentialProvider credentialProvider;
+
+ @Autowired private EidasProxyServiceController eidasProxyEndpoint;
+ @Autowired private ProtocolFinalizationController finalize;
+
+ @Autowired private IStatusMessenger messager;
+
+ /**
+ * jUnit class initializer.
+ * @throws InterruptedException In case of an error
+ * @throws ComponentInitializationException In case of an error
+ * @throws InitializationException In case of an error
+ *
+ */
+ @BeforeClass
+ @SneakyThrows
+ public static void classInitializer() {
+ final String current = new java.io.File(".").toURI().toString();
+ System.clearProperty("eidas.ms.configuration");
+
+ //eIDAS Ref. Impl. properties
+ System.setProperty("EIDAS_CONFIG_REPOSITORY", current.substring("file:".length())
+ + "../basicConfig/eIDAS/");
+ System.setProperty("SPECIFIC_CONNECTOR_CONFIG_REPOSITORY", current.substring("file:".length())
+ + "../basicConfig/eIDAS/");
+ System.setProperty("SPECIFIC_PROXY_SERVICE_CONFIG_REPOSITORY", current.substring("file:".length())
+ + "../basicConfig/eIDAS/");
+
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ }
+
+ /**
+ * Test shut-down.
+ *
+ * @throws Exception In case of an error
+ */
+ @AfterClass
+ @SneakyThrows
+ public static void closeIgniteNode() {
+ System.out.println("Closiong Ignite Node ... ");
+ Ignition.stopAll(true);
+
+ //set Ignite-node holder to 'null' because static holders are shared between different tests
+ final Field field = IgniteInstanceInitializerSpecificCommunication.class.getDeclaredField("instance");
+ field.setAccessible(true);
+ field.set(null, null);
+
+ }
+
+ /**
+ * jUnit test set-up.
+ *
+ *
+ */
+ @Before
+ public void setup() throws IOException {
+ DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac);
+ @SuppressWarnings("rawtypes")
+ Map<String, FilterRegistrationBean> filters = wac.getBeansOfType(FilterRegistrationBean.class);
+ for (FilterRegistrationBean<?> filter : filters.values()) {
+ if (filter.isEnabled()) {
+ builder.addFilter(filter.getFilter(), "/*");
+
+ }
+ }
+
+ LogMessageProviderFactory.setStatusMessager(messager);
+
+ }
+
+ @Test
+ @SneakyThrows
+ public void simpleError() {
+ MockHttpServletRequest proxyHttpReq = new MockHttpServletRequest("POST", "https://localhost/ms_proxy");
+ String spCountryCode = injectEidas2AuthnReq(proxyHttpReq);
+ MockHttpServletResponse proxyHttpResp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(proxyHttpReq, proxyHttpResp));
+
+ injectIdAustriaSaml2Metadata();
+
+
+ // send eIDAS Proxy-Service process hand-over
+ eidasProxyEndpoint.receiveEidasAuthnRequest(proxyHttpReq, proxyHttpResp);
+
+
+ // extract SAML2 AuthnRequest to IDA system
+ assertEquals("forward to finalization", 200, proxyHttpResp.getStatus());
+ assertEquals("forward to eIDAS Node page", "text/html;charset=UTF-8", proxyHttpResp.getContentType());
+ String saml2ReqPage = proxyHttpResp.getContentAsString();
+ assertNotNull("selectionPage is null", saml2ReqPage);
+ assertFalse("selectionPage is empty", saml2ReqPage.isEmpty());
+
+ String saml2ReqB64 = extractRequestToken(saml2ReqPage, "<input type=\"hidden\" name=\"SAMLRequest\" value=\"");
+ String saml2RelayState = extractRequestToken(saml2ReqPage, "<input type=\"hidden\" name=\"RelayState\" value=\"");
+ assertNotNull("SAML2 request", saml2ReqB64);
+ assertNotNull("SAML2 relayState", saml2RelayState);
+
+
+
+ // send WRONG response from IDA system to eIDAS Proxy-Service
+ final MockHttpServletRequest idaHttpReq = new MockHttpServletRequest("POST", "https://localhost/ms_proxy");
+ idaHttpReq.setScheme("https");
+ idaHttpReq.setServerPort(443);
+ idaHttpReq.setContextPath("/ms_proxy");
+ idaHttpReq.addParameter(IdAustriaAuthSignalController.HTTP_PARAM_RELAYSTATE, RandomStringUtils.randomAlphanumeric(15));
+ idaHttpReq.addParameter("SAMLResponse", RandomStringUtils.randomAlphabetic(25));
+ final MockHttpServletResponse idaHttpResp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(idaHttpReq, idaHttpResp));
+
+ idAustriaEndpoint.performEidasAuthentication(idaHttpReq, idaHttpResp);
+
+
+ // validate forwarding to protocol finalization
+ assertEquals("forward to finalization", 302, idaHttpResp.getStatus());
+ assertNotNull("missing redirect header", idaHttpResp.getHeader("Location"));
+ assertTrue("wrong redirect header", idaHttpResp.getHeader("Location").startsWith(ERROR_REDIRECT));
+ String finalPendingReqId = idaHttpResp.getHeader("Location").substring(ERROR_REDIRECT.length());
+ assertFalse("final errorId", finalPendingReqId.isEmpty());
+
+ // set-up error-handling request
+ MockHttpServletRequest finalizationReq = new MockHttpServletRequest("POST", "https://localhost/ms_proxy");
+ finalizationReq.setParameter("errorid", finalPendingReqId);
+ MockHttpServletResponse respErrorPage = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(finalizationReq, respErrorPage));
+
+ // execute error-handling step
+ finalize.errorHandling(finalizationReq, respErrorPage);
+
+
+ // extract access-token for eIDAS node communication
+ assertEquals("errorPage", 200, respErrorPage.getStatus());
+ assertEquals("errorPage", "text/html;charset=UTF-8", respErrorPage.getContentType());
+ String errorPage = respErrorPage.getContentAsString();
+ assertNotNull("errorPage is null", errorPage);
+ assertFalse("errorPage is empty", errorPage.isEmpty());
+ assertTrue("Missing errorCode", errorPage.contains("auth.26"));
+
+ }
+
+ @Test
+ @SneakyThrows
+ public void simpleSuccess() {
+ MockHttpServletRequest proxyHttpReq = new MockHttpServletRequest("POST", "https://localhost/ms_proxy");
+ String spCountryCode = injectEidas2AuthnReq(proxyHttpReq);
+ MockHttpServletResponse proxyHttpResp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(proxyHttpReq, proxyHttpResp));
+
+ injectIdAustriaSaml2Metadata();
+
+
+ // send eIDAS Proxy-Service process hand-over
+ eidasProxyEndpoint.receiveEidasAuthnRequest(proxyHttpReq, proxyHttpResp);
+
+
+ // extract SAML2 AuthnRequest to IDA system
+ assertEquals("forward to finalization", 200, proxyHttpResp.getStatus());
+ assertEquals("forward to eIDAS Node page", "text/html;charset=UTF-8", proxyHttpResp.getContentType());
+ String saml2ReqPage = proxyHttpResp.getContentAsString();
+ assertNotNull("selectionPage is null", saml2ReqPage);
+ assertFalse("selectionPage is empty", saml2ReqPage.isEmpty());
+
+ String saml2ReqB64 = extractRequestToken(saml2ReqPage, "<input type=\"hidden\" name=\"SAMLRequest\" value=\"");
+ String saml2RelayState = extractRequestToken(saml2ReqPage, "<input type=\"hidden\" name=\"RelayState\" value=\"");
+ assertNotNull("SAML2 request", saml2ReqB64);
+ assertNotNull("SAML2 relayState", saml2RelayState);
+
+ // validate SAML2 request to IDA system
+ String saml2ReqId = validateSaml2Request(saml2ReqB64, spCountryCode);
+
+ // build SAML2 response from IDA system
+ String saml2RespB64 = buildSaml2Response(saml2ReqId);
+
+
+ // send response from IDA system to eIDAS Proxy-Service
+ final MockHttpServletRequest idaHttpReq = new MockHttpServletRequest("POST", "https://localhost/ms_proxy");
+ idaHttpReq.setScheme("https");
+ idaHttpReq.setServerPort(443);
+ idaHttpReq.setContextPath("/ms_proxy");
+ idaHttpReq.addParameter(IdAustriaAuthSignalController.HTTP_PARAM_RELAYSTATE, saml2RelayState);
+ idaHttpReq.addParameter("SAMLResponse", saml2RespB64);
+ final MockHttpServletResponse idaHttpResp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(idaHttpReq, idaHttpResp));
+
+ idAustriaEndpoint.performEidasAuthentication(idaHttpReq, idaHttpResp);
+
+
+ // validate forwarding to protocol finalization
+ assertEquals("forward to finalization", 302, idaHttpResp.getStatus());
+ assertNotNull("missing redirect header", idaHttpResp.getHeader("Location"));
+ assertTrue("wrong redirect header", idaHttpResp.getHeader("Location").startsWith(FINAL_REDIRECT));
+ String finalPendingReqId = idaHttpResp.getHeader("Location").substring(FINAL_REDIRECT.length());
+ assertFalse("final pendingRequestId", finalPendingReqId.isEmpty());
+
+ // set-up finalization request
+ MockHttpServletRequest finalizationReq = new MockHttpServletRequest("POST", "https://localhost/ms_proxy");
+ finalizationReq.setParameter("pendingid", finalPendingReqId);
+ MockHttpServletResponse respToEidasProxy = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(finalizationReq, respToEidasProxy));
+
+ // exexcute finalization step
+ finalize.finalizeAuthProtocol(finalizationReq, respToEidasProxy);
+
+
+ // extract access-token for eIDAS node communication
+ assertEquals("forward to finalization", 200, respToEidasProxy.getStatus());
+ assertEquals("forward to eIDAS Node page", "text/html;charset=UTF-8", respToEidasProxy.getContentType());
+ String forwardPage = respToEidasProxy.getContentAsString();
+ assertNotNull("forward to eIDAS Node is null", forwardPage);
+ assertFalse("forward to eIDAS Node is empty", forwardPage.isEmpty());
+
+ String eidasNodeRespToken = extractRequestToken(forwardPage, "<input type=\"hidden\" name=\"token\" value=\"");
+ assertFalse("eidas req. token", eidasNodeRespToken.isEmpty());
+
+ // validate eIDAS light-response to eIDAS node
+ validateEidasLightResponse(eidasNodeRespToken);
+
+
+ }
+
+
+ @SneakyThrows
+ private void validateEidasLightResponse(String eidasNodeRespToken) {
+ final SpecificCommunicationService springManagedSpecificConnectorCommunicationService =
+ (SpecificCommunicationService) wac.getBean(
+ SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE.toString());
+
+ ILightResponse lightResp = springManagedSpecificConnectorCommunicationService.getAndRemoveResponse(eidasNodeRespToken,
+ attrRegistry.getCoreAttributeRegistry().getAttributes());
+
+ SimpleDateFormat dateTimeParser = new SimpleDateFormat("yyyy-MM-dd");
+ dateTimeParser.setTimeZone(TimeZone.getTimeZone("UTC"));
+
+ assertNotNull("ligth-response", lightResp);
+ assertEquals("eIDAS statusCode", "urn:oasis:names:tc:SAML:2.0:status:Success", lightResp.getStatus().getStatusCode());
+ assertEquals("eIDAS LoA", "http://eidas.europa.eu/LoA/high", lightResp.getLevelOfAssurance());
+ assertEquals("eIDAS attribute size", 4, lightResp.getAttributes().size());
+ checkEidasAttribute(lightResp.getAttributes(),
+ "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", "QVGm48cqcM4UcyhDTNGYmVdrIoY=");
+ checkEidasAttribute(lightResp.getAttributes(),
+ "http://eidas.europa.eu/attributes/naturalperson/CurrentGivenName", "Max");
+ checkEidasAttribute(lightResp.getAttributes(),
+ "http://eidas.europa.eu/attributes/naturalperson/CurrentFamilyName", "Mustermann");
+ checkEidasAttribute(lightResp.getAttributes(),
+ "http://eidas.europa.eu/attributes/naturalperson/DateOfBirth",
+ new DateTime(dateTimeParser.parse("1940-01-01").getTime(), DateTimeZone.UTC));
+
+
+
+ }
+
+ private void checkEidasAttribute(ImmutableAttributeMap attributes, String attrName, Object expected) {
+ ImmutableSet<? extends AttributeValue<Object>> attr = attributes.getAttributeValuesByNameUri(attrName);
+ assertNotNull("Attribute: " + attrName, attr);
+ assertFalse("Empty AttributeValue: " + attrName, attr.isEmpty());
+ assertNotNull("AttributeValue: " + attrName, attr.asList().get(0));
+ assertEquals("Wrong AttributeValue: " + attrName, expected, attr.asList().get(0).getValue());
+
+ }
+
+ @SneakyThrows
+ private String validateSaml2Request(String saml2ReqB64, String spCountryCode) {
+ final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ new ByteArrayInputStream(Base64Utils.decodeFromString(saml2ReqB64)));
+
+ // check requested attributes
+ assertEquals("wrong number of extension elements",
+ 1, authnReq.getExtensions().getOrderedChildren().size());
+ assertEquals("wrong number of requested attributes",
+ 5, authnReq.getExtensions().getOrderedChildren().get(0).getOrderedChildren().size());
+
+ return authnReq.getID();
+ }
+
+ @SneakyThrows
+ private String buildSaml2Response(String saml2ReqId) {
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_with_EID.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true, saml2ReqId);
+ return Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8"));
+
+ }
+
+ private Response initializeResponse(String idpEntityId, String responsePath, EaafX509Credential credential,
+ boolean validConditions, String saml2ReqId) throws SamlSigningException, XMLParserException, UnmarshallingException,
+ Pvp2MetadataException {
+
+ final Response response = (Response) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ FullStartUpAndProcessTest.class.getResourceAsStream(responsePath));
+ response.setIssueInstant(Instant.now());
+ final Issuer issuer = Saml2Utils.createSamlObject(Issuer.class);
+ issuer.setValue(idpEntityId);
+ response.setIssuer(issuer);
+ response.setInResponseTo(saml2ReqId);
+
+ if (validConditions) {
+ response.getAssertions().get(0).getConditions().setNotOnOrAfter(Instant.now().plusSeconds(5*60));
+
+ }
+
+ return Saml2Utils.signSamlObject(response, credential, true);
+ }
+
+ @SneakyThrows
+ private void injectIdAustriaSaml2Metadata() {
+ final org.springframework.core.io.Resource resource = resourceLoader.getResource(METADATA_PATH);
+ Timer timer = new Timer("PVP metadata-resolver refresh");
+ ResourceBackedMetadataResolver fileSystemResolver =
+ new ResourceBackedMetadataResolver(timer, new OpenSaml3ResourceAdapter(resource));
+ fileSystemResolver.setId("test");
+ fileSystemResolver.setParserPool(XMLObjectProviderRegistrySupport.getParserPool());
+ fileSystemResolver.initialize();
+ idAustriaMetadata.addMetadataResolverIntoChain(fileSystemResolver);
+
+
+ }
+
+ private String extractRequestToken(String selectionPage, String selector) {
+ int start = selectionPage.indexOf(selector);
+ assertTrue("find no starting element of selector", start > 0);
+ int end = selectionPage.indexOf("\"", start + selector.length());
+ assertTrue("find no end tag", end > 0);
+ return selectionPage.substring(start + selector.length(), end);
+
+ }
+
+ @SneakyThrows
+ private String injectEidas2AuthnReq(MockHttpServletRequest proxyHttpReq) {
+ String spCountryCode = "XX";
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_PERSONALIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_CURRENTGIVENNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_CURRENTFAMILYNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_DATEOFBIRTH).first())
+ .build());
+
+ final SpecificCommunicationService springManagedSpecificConnectorCommunicationService =
+ (SpecificCommunicationService) wac.getBean(
+ SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE.toString());
+ BinaryLightToken token = springManagedSpecificConnectorCommunicationService.putRequest(authnReqBuilder.build());
+ proxyHttpReq.addParameter(EidasParameterKeys.TOKEN.toString(), Base64Utils.encodeToString(token.getTokenBytes()));
+
+ return spCountryCode;
+
+ }
+
+}
diff --git a/ms_specific_proxyservice/src/test/java/at/asitplus/eidas/specific/proxy/test/MsConnectorSpringResourceProviderTest.java b/ms_specific_proxyservice/src/test/java/at/asitplus/eidas/specific/proxy/test/MsConnectorSpringResourceProviderTest.java
new file mode 100644
index 00000000..2da6b316
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/java/at/asitplus/eidas/specific/proxy/test/MsConnectorSpringResourceProviderTest.java
@@ -0,0 +1,56 @@
+package at.asitplus.eidas.specific.proxy.test;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.springframework.core.io.Resource;
+
+import at.asitplus.eidas.specific.proxy.MsSpecificEidasProxySpringResourceProvider;
+import at.gv.egiz.eaaf.core.test.TestConstants;
+
+
+
+@RunWith(BlockJUnit4ClassRunner.class)
+public class MsConnectorSpringResourceProviderTest {
+
+ @Test
+ public void testSpringConfig() {
+ final MsSpecificEidasProxySpringResourceProvider test =
+ new MsSpecificEidasProxySpringResourceProvider();
+ for (final Resource el : test.getResourcesToLoad()) {
+ try {
+ IOUtils.toByteArray(el.getInputStream());
+
+ } catch (final IOException e) {
+ Assert.fail("Ressouce: " + el.getFilename() + " not found");
+ }
+
+ }
+
+ Assert.assertNotNull("no Name", test.getName());
+ Assert.assertNull("Find package definitions", test.getPackagesToScan());
+
+ }
+
+ @Test
+ public void testSpILoaderConfig() {
+ final InputStream el = this.getClass().getResourceAsStream(TestConstants.TEST_SPI_LOADER_PATH);
+ try {
+ final String spiFile = IOUtils.toString(el, "UTF-8");
+
+ Assert.assertEquals("Wrong classpath in SPI file",
+ MsSpecificEidasProxySpringResourceProvider.class.getName(), spiFile);
+
+
+ } catch (final IOException e) {
+ Assert.fail("Ressouce: " + TestConstants.TEST_SPI_LOADER_PATH + " not found");
+
+ }
+ }
+
+}
diff --git a/ms_specific_proxyservice/src/test/java/at/asitplus/eidas/specific/proxy/test/builder/ProxyAuthenticationDataBuilderTest.java b/ms_specific_proxyservice/src/test/java/at/asitplus/eidas/specific/proxy/test/builder/ProxyAuthenticationDataBuilderTest.java
new file mode 100644
index 00000000..ee2c8d8c
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/java/at/asitplus/eidas/specific/proxy/test/builder/ProxyAuthenticationDataBuilderTest.java
@@ -0,0 +1,395 @@
+package at.asitplus.eidas.specific.proxy.test.builder;
+
+import static at.asitplus.eidas.specific.core.MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.RandomUtils;
+import org.apache.ignite.Ignition;
+import org.junit.AfterClass;
+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.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.annotation.DirtiesContext.ClassMode;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import com.google.common.collect.Sets;
+
+import at.asitplus.eidas.specific.core.MsEidasNodeConstants;
+import at.asitplus.eidas.specific.core.builder.AuthenticationDataBuilder;
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.gv.egiz.components.spring.api.SpringBootApplicationContextInitializer;
+import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
+import at.gv.egiz.eaaf.core.impl.idp.EidAuthenticationData;
+import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper;
+import at.gv.egiz.eaaf.core.impl.idp.auth.data.EidAuthProcessDataWrapper;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import eu.eidas.auth.cache.IgniteInstanceInitializerSpecificCommunication;
+import lombok.SneakyThrows;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest
+@ContextConfiguration(initializers = {
+ org.springframework.boot.context.config.DelegatingApplicationContextInitializer.class,
+ SpringBootApplicationContextInitializer.class
+ })
+@TestPropertySource(locations = { "file:src/test/resources/config/junit_config_1_springboot.properties" })
+@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
+@ActiveProfiles(profiles = {"JUNIT", "jUnitTestMode"})
+public class ProxyAuthenticationDataBuilderTest {
+
+
+ @Autowired
+ private AuthenticationDataBuilder authenticationDataBuilder;
+
+ @Autowired(required = true)
+ private IConfiguration basicConfig;
+
+ private MockHttpServletRequest httpReq;
+ private MockHttpServletResponse httpResp;
+ private TestRequestImpl pendingReq;
+
+ private Map<String, String> spConfig;
+ private ServiceProviderConfiguration oaParam;
+
+ private String eidasBind;
+ private String authBlock;
+
+ @BeforeClass
+ public static void classInitializer() throws InitializationException, ComponentInitializationException {
+ final String current = new java.io.File(".").toURI().toString();
+ System.setProperty("eidas.ms.configuration", current
+ + "src/test/resources/config/junit_config_3.properties");
+
+ //eIDAS Ref. Impl. properties
+ System.setProperty("EIDAS_CONFIG_REPOSITORY", current.substring("file:".length())
+ + "../basicConfig/eIDAS/");
+ System.setProperty("SPECIFIC_CONNECTOR_CONFIG_REPOSITORY", current.substring("file:".length())
+ + "../basicConfig/eIDAS/");
+ System.setProperty("SPECIFIC_PROXY_SERVICE_CONFIG_REPOSITORY", current.substring("file:".length())
+ + "../basicConfig/eIDAS/");
+
+ EaafOpenSaml3xInitializer.eaafInitialize();
+ }
+
+ /**
+ * Test shut-down.
+ *
+ * @throws Exception In case of an error
+ */
+ @AfterClass
+ @SneakyThrows
+ public static void closeIgniteNode() {
+ System.out.println("Closiong Ignite Node ... ");
+ Ignition.stopAll(true);
+
+ //set Ignite-node holder to 'null' because static holders are shared between different tests
+ final Field field = IgniteInstanceInitializerSpecificCommunication.class.getDeclaredField("instance");
+ field.setAccessible(true);
+ field.set(null, null);
+
+ }
+
+ @Before
+ @SneakyThrows
+ public void initialize() throws EaafStorageException {
+ httpReq = new MockHttpServletRequest("POST", "https://localhost/ms_connector");
+ httpResp = new MockHttpServletResponse();
+ RequestContextHolder.resetRequestAttributes();
+ RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp));
+
+ spConfig = new HashMap<>();
+ spConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, "testSp");
+ spConfig.put("target", "urn:publicid:gv.at:cdid+XX");
+ spConfig.put(PROP_CONFIG_SP_NEW_EID_MODE, "true");
+ oaParam = new ServiceProviderConfiguration(spConfig, basicConfig);
+ oaParam.setBpkTargetIdentifier("urn:publicid:gv.at:cdid+XX");
+
+ pendingReq = new TestRequestImpl();
+ pendingReq.setAuthUrl("https://localhost/ms_connector");
+ pendingReq.setPendingReqId(RandomStringUtils.randomAlphanumeric(10));
+ pendingReq.setPiiTransactionId(RandomStringUtils.randomAlphanumeric(10));
+ pendingReq.setSpConfig(oaParam);
+ authBlock = RandomStringUtils.randomAlphanumeric(20);
+ eidasBind = RandomStringUtils.randomAlphanumeric(20);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(MsEidasNodeConstants.AUTH_DATA_SZR_AUTHBLOCK, authBlock);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(MsEidasNodeConstants.AUTH_DATA_EIDAS_BIND, eidasBind);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setQaaLevel(EaafConstants.EIDAS_LOA_PREFIX + RandomStringUtils.randomAlphabetic(5));
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ PvpAttributeDefinitions.EID_ISSUING_NATION_NAME,
+ RandomStringUtils.randomAlphabetic(2));
+
+ LocaleContextHolder.resetLocaleContext();
+
+ }
+
+ @Test
+ @SneakyThrows
+ public void eidasProxyModeSimple() throws EaafAuthenticationException {
+ // initialize state
+ pendingReq = new TestRequestImpl();
+ pendingReq.setAuthUrl("https://localhost/ms_connector");
+ pendingReq.setPendingReqId(RandomStringUtils.randomAlphanumeric(10));
+ pendingReq.setPiiTransactionId(RandomStringUtils.randomAlphanumeric(10));
+ pendingReq.setSpConfig(oaParam);
+ boolean isTestIdentity = RandomUtils.nextBoolean();
+
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setEidProcess(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setForeigner(false);
+
+ String bpk = RandomStringUtils.randomAlphanumeric(10);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ PvpAttributeDefinitions.BPK_NAME, "eidas+AT+XX:" + bpk);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ PvpAttributeDefinitions.GIVEN_NAME_NAME, "Max");
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Mustermann");
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ PvpAttributeDefinitions.BIRTHDATE_NAME, "1940-01-01");
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME,
+ "http://eidas.europa.eu/LoA/high");
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ PvpAttributeDefinitions.EID_ISSUING_NATION_NAME,
+ RandomStringUtils.randomAlphabetic(2));
+
+ String randAttr = RandomStringUtils.randomAlphabetic(10);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession(
+ randAttr, RandomStringUtils.randomAlphabetic(10));
+
+ oaParam.setRequestedAttributes(Sets.newHashSet(randAttr,
+ PvpAttributeDefinitions.BPK_NAME,
+ PvpAttributeDefinitions.GIVEN_NAME_NAME,
+ PvpAttributeDefinitions.PRINCIPAL_NAME_NAME,
+ PvpAttributeDefinitions.BIRTHDATE_NAME,
+ PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME,
+ PvpAttributeDefinitions.EID_ISSUING_NATION_NAME));
+
+
+ // execute
+ IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq);
+
+ // validate state
+ Assert.assertNotNull("AuthData null", authData);
+ Assert.assertNull("authBlock null", authData.getGenericData(MsEidasNodeConstants.AUTH_DATA_SZR_AUTHBLOCK, String.class));
+ Assert.assertNull("eidasBind null", authData.getGenericData(MsEidasNodeConstants.AUTH_DATA_EIDAS_BIND, String.class));
+ Assert.assertNotNull("LoA null", authData.getEidasQaaLevel());
+
+ Assert.assertEquals("FamilyName", "Mustermann", authData.getFamilyName());
+ Assert.assertEquals("GivenName", "Max", authData.getGivenName());
+ Assert.assertEquals("DateOfBirth", "1940-01-01", authData.getDateOfBirth());
+
+ Assert.assertEquals("LoA", "http://eidas.europa.eu/LoA/high", authData.getEidasQaaLevel());
+ Assert.assertEquals("EID-ISSUING-NATION",
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).getGenericDataFromSession(
+ PvpAttributeDefinitions.EID_ISSUING_NATION_NAME),
+ authData.getCiticenCountryCode());
+
+ checkGenericAttribute(authData, PvpAttributeDefinitions.BPK_NAME, bpk);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.GIVEN_NAME_NAME, "Max");
+ checkGenericAttribute(authData, PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Mustermann");
+ checkGenericAttribute(authData, PvpAttributeDefinitions.BIRTHDATE_NAME, "1940-01-01");
+
+ Assert.assertEquals("random optional attr.",
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).getGenericDataFromSession(
+ randAttr),
+ authData.getGenericData(randAttr, String.class));
+
+ }
+
+
+ @Test
+ public void eidasProxyModeWithNatMandate() throws EaafAuthenticationException, EaafStorageException {
+ // initialize state
+ injectRepresentativeInfosIntoSession();
+
+ String givenNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String familyNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String dateOfBirthMandate = "1957-09-15";
+ String bpkMandate = RandomStringUtils.randomAlphanumeric(10);
+
+ // set nat. person mandate information
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, dateOfBirthMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, "AT+XX:" + bpkMandate);
+
+ oaParam.setRequestedAttributes(Sets.newHashSet(
+ PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME));
+
+ // execute test
+ IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq);
+
+
+ // validate state
+ Assert.assertNotNull("AuthData null", authData);
+ assertTrue("mandate flag", ((EidAuthenticationData)authData).isUseMandate());
+
+ //check mandate informations
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, "1957-09-15");
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, bpkMandate);
+
+ }
+
+ @Test
+ public void eidasProxyModeWithNatMandateWrongBpkFormat() throws EaafAuthenticationException, EaafStorageException {
+ // initialize state
+ injectRepresentativeInfosIntoSession();
+
+ String givenNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String familyNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String dateOfBirthMandate = "1957-09-15";
+ String bpkMandate = RandomStringUtils.randomAlphanumeric(10);
+
+ // set nat. person mandate information
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, dateOfBirthMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, bpkMandate);
+
+ oaParam.setRequestedAttributes(Sets.newHashSet(
+ PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME));
+
+ // execute test
+ IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq);
+
+
+ // validate state
+ Assert.assertNotNull("AuthData null", authData);
+ assertTrue("mandate flag", ((EidAuthenticationData)authData).isUseMandate());
+
+ //check mandate informations
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, "1957-09-15");
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, bpkMandate);
+
+ }
+
+ @Test
+ public void eidasProxyModeWithJurMandate() throws EaafAuthenticationException, EaafStorageException {
+ // initialize state
+ injectRepresentativeInfosIntoSession();
+
+ String commonMandate = RandomStringUtils.randomAlphabetic(10);
+
+ // set constant country-code and sourcePin to check hashed eIDAS identifier
+ String sourcePinMandate = "asfdsadfsadfsafsdafsadfasr";
+ spConfig.put("target", EaafConstants.URN_PREFIX_EIDAS + "AT+EE");
+
+ // set nat. person mandate information
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, commonMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, sourcePinMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME,
+ EaafConstants.URN_PREFIX_BASEID + "+XFN");
+
+ oaParam.setRequestedAttributes(Sets.newHashSet(
+ PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME,
+ PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME,
+ PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME));
+
+ // execute test
+ IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq);
+
+
+ // validate state
+ Assert.assertNotNull("AuthData null", authData);
+ assertTrue("mandate flag", ((EidAuthenticationData)authData).isUseMandate());
+
+ //check mandate informations
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, commonMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, "XFN+" + sourcePinMandate);
+
+ }
+
+ private void injectRepresentativeInfosIntoSession() throws EaafStorageException {
+ boolean isTestIdentity = RandomUtils.nextBoolean();
+ pendingReq.getSessionData(EidAuthProcessDataWrapper.class).setTestIdentity(isTestIdentity);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setEidProcess(true);
+
+ String givenName = RandomStringUtils.randomAlphabetic(10);
+ String familyName = RandomStringUtils.randomAlphabetic(10);
+ String dateOfBirth = "1956-12-08";
+ String bpk = RandomStringUtils.randomAlphanumeric(10);
+ String cc = pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .getGenericDataFromSession(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, String.class);
+ String spC = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ spConfig.put("target", EaafConstants.URN_PREFIX_EIDAS + cc + "+" + spC);
+
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setEidProcess(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setForeigner(false);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.GIVEN_NAME_NAME, givenName);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, familyName);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.BIRTHDATE_NAME, dateOfBirth);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.BPK_NAME, bpk);
+
+ //set LoA level attribute instead of explicit session-data
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME,
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).getQaaLevel());
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setQaaLevel(null);
+
+ }
+
+ private void checkGenericAttribute(IAuthData authData, String attrName, String expected) {
+ assertEquals("Wrong: " + attrName, expected, authData.getGenericData(attrName, String.class));
+
+ }
+
+}
diff --git a/ms_specific_proxyservice/src/test/resources/config/eIDAS/additional-attributes.xml b/ms_specific_proxyservice/src/test/resources/config/eIDAS/additional-attributes.xml
new file mode 100644
index 00000000..6510546e
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/eIDAS/additional-attributes.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+# Copyright (c) 2017 European Commission
+# Licensed under the EUPL, Version 1.2 or – as soon they will be
+# approved by the European Commission - subsequent versions of the
+# EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+# * https://joinup.ec.europa.eu/page/eupl-text-11-12
+# *
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the Licence is distributed on an "AS IS" basis,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the Licence for the specific language governing permissions and limitations under the Licence.
+ -->
+
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+ <comment>Dynamic attributes</comment>
+
+ <entry key="1.NameUri">http://eidas.europa.eu/attributes/naturalperson/AdditionalAttribute</entry>
+ <entry key="1.FriendlyName">AdditionalAttribute</entry>
+ <entry key="1.PersonType">NaturalPerson</entry>
+ <entry key="1.Required">false</entry>
+ <entry key="1.XmlType.NamespaceUri">http://www.w3.org/2001/XMLSchema</entry>
+ <entry key="1.XmlType.LocalPart">string</entry>
+ <entry key="1.XmlType.NamespacePrefix">xs</entry>
+ <entry key="1.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="2.NameUri">http://eidas.europa.eu/attributes/legalperson/LegalAdditionalAttribute</entry>
+ <entry key="2.FriendlyName">LegalAdditionalAttribute</entry>
+ <entry key="2.PersonType">LegalPerson</entry>
+ <entry key="2.Required">false</entry>
+ <entry key="2.XmlType.NamespaceUri">http://www.w3.org/2001/XMLSchema</entry>
+ <entry key="2.XmlType.LocalPart">string</entry>
+ <entry key="2.XmlType.NamespacePrefix">xs</entry>
+ <entry key="2.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+</properties>
diff --git a/ms_specific_proxyservice/src/test/resources/config/eIDAS/eidas-attributes.xml b/ms_specific_proxyservice/src/test/resources/config/eIDAS/eidas-attributes.xml
new file mode 100644
index 00000000..cbae35db
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/eIDAS/eidas-attributes.xml
@@ -0,0 +1,376 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+# Copyright (c) 2017 European Commission
+# Licensed under the EUPL, Version 1.2 or – as soon they will be
+# approved by the European Commission - subsequent versions of the
+# EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+# * https://joinup.ec.europa.eu/page/eupl-text-11-12
+# *
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the Licence is distributed on an "AS IS" basis,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the Licence for the specific language governing permissions and limitations under the Licence.
+ -->
+
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+ <comment>eIDAS attributes</comment>
+
+ <entry key="1.NameUri">http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier</entry>
+ <entry key="1.FriendlyName">PersonIdentifier</entry>
+ <entry key="1.PersonType">NaturalPerson</entry>
+ <entry key="1.Required">true</entry>
+ <entry key="1.UniqueIdentifier">true</entry>
+ <entry key="1.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="1.XmlType.LocalPart">PersonIdentifierType</entry>
+ <entry key="1.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="1.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="2.NameUri">http://eidas.europa.eu/attributes/naturalperson/CurrentFamilyName</entry>
+ <entry key="2.FriendlyName">FamilyName</entry>
+ <entry key="2.PersonType">NaturalPerson</entry>
+ <entry key="2.Required">true</entry>
+ <entry key="2.TransliterationMandatory">true</entry>
+ <entry key="2.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="2.XmlType.LocalPart">CurrentFamilyNameType</entry>
+ <entry key="2.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="2.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="3.NameUri">http://eidas.europa.eu/attributes/naturalperson/CurrentGivenName</entry>
+ <entry key="3.FriendlyName">FirstName</entry>
+ <entry key="3.PersonType">NaturalPerson</entry>
+ <entry key="3.Required">true</entry>
+ <entry key="3.TransliterationMandatory">true</entry>
+ <entry key="3.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="3.XmlType.LocalPart">CurrentGivenNameType</entry>
+ <entry key="3.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="3.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="4.NameUri">http://eidas.europa.eu/attributes/naturalperson/DateOfBirth</entry>
+ <entry key="4.FriendlyName">DateOfBirth</entry>
+ <entry key="4.PersonType">NaturalPerson</entry>
+ <entry key="4.Required">true</entry>
+ <entry key="4.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="4.XmlType.LocalPart">DateOfBirthType</entry>
+ <entry key="4.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="4.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.DateTimeAttributeValueMarshaller</entry>
+
+ <entry key="5.NameUri">http://eidas.europa.eu/attributes/naturalperson/BirthName</entry>
+ <entry key="5.FriendlyName">BirthName</entry>
+ <entry key="5.PersonType">NaturalPerson</entry>
+ <entry key="5.Required">false</entry>
+ <entry key="5.TransliterationMandatory">true</entry>
+ <entry key="5.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="5.XmlType.LocalPart">BirthNameType</entry>
+ <entry key="5.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="5.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="6.NameUri">http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth</entry>
+ <entry key="6.FriendlyName">PlaceOfBirth</entry>
+ <entry key="6.PersonType">NaturalPerson</entry>
+ <entry key="6.Required">false</entry>
+ <entry key="6.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="6.XmlType.LocalPart">PlaceOfBirthType</entry>
+ <entry key="6.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="6.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="7.NameUri">http://eidas.europa.eu/attributes/naturalperson/CurrentAddress</entry>
+ <entry key="7.FriendlyName">CurrentAddress</entry>
+ <entry key="7.PersonType">NaturalPerson</entry>
+ <entry key="7.Required">false</entry>
+ <entry key="7.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="7.XmlType.LocalPart">CurrentAddressType</entry>
+ <entry key="7.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="7.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.CurrentAddressAttributeValueMarshaller</entry>
+
+ <entry key="8.NameUri">http://eidas.europa.eu/attributes/naturalperson/Gender</entry>
+ <entry key="8.FriendlyName">Gender</entry>
+ <entry key="8.PersonType">NaturalPerson</entry>
+ <entry key="8.Required">false</entry>
+ <entry key="8.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson</entry>
+ <entry key="8.XmlType.LocalPart">GenderType</entry>
+ <entry key="8.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="8.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.GenderAttributeValueMarshaller</entry>
+
+ <entry key="9.NameUri">http://eidas.europa.eu/attributes/legalperson/LegalPersonIdentifier</entry>
+ <entry key="9.FriendlyName">LegalPersonIdentifier</entry>
+ <entry key="9.PersonType">LegalPerson</entry>
+ <entry key="9.Required">true</entry>
+ <entry key="9.UniqueIdentifier">true</entry>
+ <entry key="9.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="9.XmlType.LocalPart">LegalPersonIdentifierType</entry>
+ <entry key="9.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="9.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="10.NameUri">http://eidas.europa.eu/attributes/legalperson/LegalName</entry>
+ <entry key="10.FriendlyName">LegalName</entry>
+ <entry key="10.PersonType">LegalPerson</entry>
+ <entry key="10.Required">true</entry>
+ <entry key="10.TransliterationMandatory">true</entry>
+ <entry key="10.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="10.XmlType.LocalPart">LegalNameType</entry>
+ <entry key="10.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="10.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="11.NameUri">http://eidas.europa.eu/attributes/legalperson/LegalPersonAddress</entry>
+ <entry key="11.FriendlyName">LegalAddress</entry>
+ <entry key="11.PersonType">LegalPerson</entry>
+ <entry key="11.Required">false</entry>
+ <entry key="11.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="11.XmlType.LocalPart">LegalPersonAddressType</entry>
+ <entry key="11.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="11.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.LegalAddressAttributeValueMarshaller</entry>
+
+ <entry key="12.NameUri">http://eidas.europa.eu/attributes/legalperson/VATRegistrationNumber</entry>
+ <entry key="12.FriendlyName">VATRegistration</entry>
+ <entry key="12.PersonType">LegalPerson</entry>
+ <entry key="12.Required">false</entry>
+ <entry key="12.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="12.XmlType.LocalPart">VATRegistrationNumberType</entry>
+ <entry key="12.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="12.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="13.NameUri">http://eidas.europa.eu/attributes/legalperson/TaxReference</entry>
+ <entry key="13.FriendlyName">TaxReference</entry>
+ <entry key="13.PersonType">LegalPerson</entry>
+ <entry key="13.Required">false</entry>
+ <entry key="13.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="13.XmlType.LocalPart">TaxReferenceType</entry>
+ <entry key="13.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="13.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="14.NameUri">http://eidas.europa.eu/attributes/legalperson/D-2012-17-EUIdentifier</entry>
+ <entry key="14.FriendlyName">D-2012-17-EUIdentifier</entry>
+ <entry key="14.PersonType">LegalPerson</entry>
+ <entry key="14.Required">false</entry>
+ <entry key="14.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="14.XmlType.LocalPart">D-2012-17-EUIdentifierType</entry>
+ <entry key="14.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="14.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="15.NameUri">http://eidas.europa.eu/attributes/legalperson/LEI</entry>
+ <entry key="15.FriendlyName">LEI</entry>
+ <entry key="15.PersonType">LegalPerson</entry>
+ <entry key="15.Required">false</entry>
+ <entry key="15.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="15.XmlType.LocalPart">LEIType</entry>
+ <entry key="15.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="15.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="16.NameUri">http://eidas.europa.eu/attributes/legalperson/EORI</entry>
+ <entry key="16.FriendlyName">EORI</entry>
+ <entry key="16.PersonType">LegalPerson</entry>
+ <entry key="16.Required">false</entry>
+ <entry key="16.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="16.XmlType.LocalPart">EORIType</entry>
+ <entry key="16.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="16.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="17.NameUri">http://eidas.europa.eu/attributes/legalperson/SEED</entry>
+ <entry key="17.FriendlyName">SEED</entry>
+ <entry key="17.PersonType">LegalPerson</entry>
+ <entry key="17.Required">false</entry>
+ <entry key="17.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="17.XmlType.LocalPart">SEEDType</entry>
+ <entry key="17.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="17.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="18.NameUri">http://eidas.europa.eu/attributes/legalperson/SIC</entry>
+ <entry key="18.FriendlyName">SIC</entry>
+ <entry key="18.PersonType">LegalPerson</entry>
+ <entry key="18.Required">false</entry>
+ <entry key="18.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson</entry>
+ <entry key="18.XmlType.LocalPart">SICType</entry>
+ <entry key="18.XmlType.NamespacePrefix">eidas-legal</entry>
+ <entry key="18.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="19.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/PersonIdentifier</entry>
+ <entry key="19.FriendlyName">RepresentativePersonIdentifier</entry>
+ <entry key="19.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="19.Required">false</entry>
+ <entry key="19.UniqueIdentifier">true</entry>
+ <entry key="19.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="19.XmlType.LocalPart">PersonIdentifierType</entry>
+ <entry key="19.XmlType.NamespacePrefix">eidas-natural</entry>
+ <entry key="19.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="20.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/CurrentFamilyName</entry>
+ <entry key="20.FriendlyName">RepresentativeFamilyName</entry>
+ <entry key="20.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="20.Required">false</entry>
+ <entry key="20.TransliterationMandatory">true</entry>
+ <entry key="20.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="20.XmlType.LocalPart">CurrentFamilyNameType</entry>
+ <entry key="20.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="20.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="21.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/CurrentGivenName</entry>
+ <entry key="21.FriendlyName">RepresentativeFirstName</entry>
+ <entry key="21.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="21.Required">false</entry>
+ <entry key="21.TransliterationMandatory">true</entry>
+ <entry key="21.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="21.XmlType.LocalPart">CurrentGivenNameType</entry>
+ <entry key="21.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="21.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="22.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/DateOfBirth</entry>
+ <entry key="22.FriendlyName">RepresentativeDateOfBirth</entry>
+ <entry key="22.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="22.Required">false</entry>
+ <entry key="22.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="22.XmlType.LocalPart">DateOfBirthType</entry>
+ <entry key="22.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="22.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.DateTimeAttributeValueMarshaller</entry>
+
+ <entry key="23.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/BirthName</entry>
+ <entry key="23.FriendlyName">RepresentativeBirthName</entry>
+ <entry key="23.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="23.Required">false</entry>
+ <entry key="23.TransliterationMandatory">true</entry>
+ <entry key="23.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="23.XmlType.LocalPart">BirthNameType</entry>
+ <entry key="23.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="23.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="24.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/PlaceOfBirth</entry>
+ <entry key="24.FriendlyName">RepresentativePlaceOfBirth</entry>
+ <entry key="24.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="24.Required">false</entry>
+ <entry key="24.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="24.XmlType.LocalPart">PlaceOfBirthType</entry>
+ <entry key="24.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="24.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="25.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/CurrentAddress</entry>
+ <entry key="25.FriendlyName">RepresentativeCurrentAddress</entry>
+ <entry key="25.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="25.Required">false</entry>
+ <entry key="25.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="25.XmlType.LocalPart">CurrentAddressType</entry>
+ <entry key="25.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="25.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.RepvCurrentAddressAttributeValueMarshaller</entry>
+
+ <entry key="26.NameUri">http://eidas.europa.eu/attributes/naturalperson/representative/Gender</entry>
+ <entry key="26.FriendlyName">RepresentativeGender</entry>
+ <entry key="26.PersonType">RepresentativeNaturalPerson</entry>
+ <entry key="26.Required">false</entry>
+ <entry key="26.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/naturalperson/representative</entry>
+ <entry key="26.XmlType.LocalPart">GenderType</entry>
+ <entry key="26.XmlType.NamespacePrefix">eidas-reprentative-natural</entry>
+ <entry key="26.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.GenderAttributeValueMarshaller</entry>
+
+ <entry key="27.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/LegalPersonIdentifier</entry>
+ <entry key="27.FriendlyName">RepresentativeLegalPersonIdentifier</entry>
+ <entry key="27.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="27.Required">false</entry>
+ <entry key="27.UniqueIdentifier">true</entry>
+ <entry key="27.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="27.XmlType.LocalPart">LegalPersonIdentifierType</entry>
+ <entry key="27.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="27.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="28.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/LegalName</entry>
+ <entry key="28.FriendlyName">RepresentativeLegalName</entry>
+ <entry key="28.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="28.Required">false</entry>
+ <entry key="28.TransliterationMandatory">true</entry>
+ <entry key="28.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="28.XmlType.LocalPart">LegalNameType</entry>
+ <entry key="28.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="28.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="29.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/LegalPersonAddress</entry>
+ <entry key="29.FriendlyName">RepresentativeLegalAddress</entry>
+ <entry key="29.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="29.Required">false</entry>
+ <entry key="29.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="29.XmlType.LocalPart">LegalPersonAddressType</entry>
+ <entry key="29.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="29.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.RepvLegalAddressAttributeValueMarshaller</entry>
+
+ <entry key="30.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/VATRegistrationNumber</entry>
+ <entry key="30.FriendlyName">RepresentativeVATRegistration</entry>
+ <entry key="30.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="30.Required">false</entry>
+ <entry key="30.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="30.XmlType.LocalPart">VATRegistrationNumberType</entry>
+ <entry key="30.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="30.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="31.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/TaxReference</entry>
+ <entry key="31.FriendlyName">RepresentativeTaxReference</entry>
+ <entry key="31.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="31.Required">false</entry>
+ <entry key="31.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="31.XmlType.LocalPart">TaxReferenceType</entry>
+ <entry key="31.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="31.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="32.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/D-2012-17-EUIdentifier</entry>
+ <entry key="32.FriendlyName">RepresentativeD-2012-17-EUIdentifier</entry>
+ <entry key="32.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="32.Required">false</entry>
+ <entry key="32.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="32.XmlType.LocalPart">D-2012-17-EUIdentifierType</entry>
+ <entry key="32.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="32.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="33.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/LEI</entry>
+ <entry key="33.FriendlyName">RepresentativeLEI</entry>
+ <entry key="33.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="33.Required">false</entry>
+ <entry key="33.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="33.XmlType.LocalPart">LEIType</entry>
+ <entry key="33.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="33.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="34.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/EORI</entry>
+ <entry key="34.FriendlyName">RepresentativeEORI</entry>
+ <entry key="34.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="34.Required">false</entry>
+ <entry key="34.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="34.XmlType.LocalPart">EORIType</entry>
+ <entry key="34.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="34.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="35.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/SEED</entry>
+ <entry key="35.FriendlyName">RepresentativeSEED</entry>
+ <entry key="35.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="35.Required">false</entry>
+ <entry key="35.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="35.XmlType.LocalPart">SEEDType</entry>
+ <entry key="35.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="35.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="36.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/SIC</entry>
+ <entry key="36.FriendlyName">RepresentativeSIC</entry>
+ <entry key="36.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="36.Required">false</entry>
+ <entry key="36.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="36.XmlType.LocalPart">SICType</entry>
+ <entry key="36.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="36.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+ <entry key="39.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/LegalPersonAddress</entry>
+ <entry key="39.FriendlyName">RepresentativeLegalAddress</entry>
+ <entry key="39.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="39.Required">false</entry>
+ <entry key="39.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="39.XmlType.LocalPart">LegalPersonAddressType</entry>
+ <entry key="39.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="39.AttributeValueMarshaller">eu.eidas.auth.commons.protocol.eidas.impl.RepvLegalAddressAttributeValueMarshaller</entry>
+
+ <entry key="40.NameUri">http://eidas.europa.eu/attributes/legalperson/representative/VATRegistrationNumber</entry>
+ <entry key="40.FriendlyName">RepresentativeVATRegistration</entry>
+ <entry key="40.PersonType">RepresentativeLegalPerson</entry>
+ <entry key="40.Required">false</entry>
+ <entry key="40.XmlType.NamespaceUri">http://eidas.europa.eu/attributes/legalperson/representative</entry>
+ <entry key="40.XmlType.LocalPart">VATRegistrationNumberType</entry>
+ <entry key="40.XmlType.NamespacePrefix">eidas-reprentative-legal</entry>
+ <entry key="40.AttributeValueMarshaller">eu.eidas.auth.commons.attribute.impl.LiteralStringAttributeValueMarshaller</entry>
+
+
+</properties>
diff --git a/ms_specific_proxyservice/src/test/resources/config/eIDAS/igniteSpecificCommunication.xml b/ms_specific_proxyservice/src/test/resources/config/eIDAS/igniteSpecificCommunication.xml
new file mode 100644
index 00000000..f817f5a4
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/eIDAS/igniteSpecificCommunication.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Copyright (c) 2018 by European Commission
+ ~
+ ~ Licensed under the EUPL, Version 1.2 or - as soon they will be
+ ~ approved by the European Commission - subsequent versions of the
+ ~ EUPL (the "Licence");
+ ~ You may not use this work except in compliance with the Licence.
+ ~ You may obtain a copy of the Licence at:
+ ~ https://joinup.ec.europa.eu/page/eupl-text-11-12
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the Licence is distributed on an "AS IS" basis,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ ~ implied.
+ ~ See the Licence for the specific language governing permissions and
+ ~ limitations under the Licence.
+ -->
+
+<!--
+ Ignite Spring configuration file to startup Ignite cache.
+
+ This file demonstrates how to configure cache using Spring. Provided cache
+ will be created on node startup.
+
+ Use this configuration file when running HTTP REST examples (see 'examples/rest' folder).
+
+ When starting a standalone node, you need to execute the following command:
+ {IGNITE_HOME}/bin/ignite.{bat|sh} examples/config/ignite-cache.xml
+
+ When starting Ignite from Java IDE, pass path to this file to Ignition:
+ Ignition.start("examples/config/ignite-cache.xml");
+-->
+
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <bean id="igniteSpecificCommunication.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+
+ <property name="igniteInstanceName" value="igniteSpecificCommunication"/>
+
+ <property name="cacheConfiguration">
+ <list>
+
+ <!--Specific Communication Caches-->
+ <!-- Partitioned cache example configuration (Atomic mode). -->
+ <bean class="org.apache.ignite.configuration.CacheConfiguration">
+ <property name="name" value="specificNodeConnectorRequestCache"/>
+ <property name="atomicityMode" value="ATOMIC"/>
+ <property name="backups" value="1"/>
+ </bean>
+ <!-- Partitioned cache example configuration (Atomic mode). -->
+ <bean class="org.apache.ignite.configuration.CacheConfiguration">
+ <property name="name" value="nodeSpecificProxyserviceRequestCache"/>
+ <property name="atomicityMode" value="ATOMIC"/>
+ <property name="backups" value="1"/>
+ </bean>
+ <!-- Partitioned cache example configuration (Atomic mode). -->
+ <bean class="org.apache.ignite.configuration.CacheConfiguration">
+ <property name="name" value="specificNodeProxyserviceResponseCache"/>
+ <property name="atomicityMode" value="ATOMIC"/>
+ <property name="backups" value="1"/>
+ </bean>
+ <!-- Partitioned cache example configuration (Atomic mode). -->
+ <bean class="org.apache.ignite.configuration.CacheConfiguration">
+ <property name="name" value="nodeSpecificConnectorResponseCache"/>
+ <property name="atomicityMode" value="ATOMIC"/>
+ <property name="backups" value="1"/>
+ </bean>
+ <!-- Partitioned cache example configuration (Atomic mode). -->
+ <bean class="org.apache.ignite.configuration.CacheConfiguration">
+ <property name="name" value="msConnectorCache"/>
+ <property name="atomicityMode" value="ATOMIC"/>
+ <property name="backups" value="1"/>
+ </bean>
+
+ </list>
+ </property>
+
+ <!--Multicast discover of other nodes in the grid configuration-->
+ <property name="discoverySpi">
+ <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+ <property name="ipFinder">
+ <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
+ <property name="multicastGroup" value="228.10.10.157"/>
+ </bean>
+ </property>
+ </bean>
+ </property>
+
+ <!-- how frequently Ignite will output basic node metrics into the log-->
+ <property name="metricsLogFrequency" value="#{60 * 10 * 1000}"/>
+
+ </bean>
+
+ <!--
+ Initialize property configurer so we can reference environment variables.
+ -->
+ <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+ <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK"/>
+ <property name="searchSystemEnvironment" value="true"/>
+ </bean>
+
+</beans>
diff --git a/ms_specific_proxyservice/src/test/resources/config/eIDAS/specificCommunicationDefinitionConnector.xml b/ms_specific_proxyservice/src/test/resources/config/eIDAS/specificCommunicationDefinitionConnector.xml
new file mode 100644
index 00000000..d1fc042d
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/eIDAS/specificCommunicationDefinitionConnector.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+# Copyright (c) 2017 European Commission
+# Licensed under the EUPL, Version 1.2 or – as soon they will be
+# approved by the European Commission - subsequent versions of the
+# EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+# * https://joinup.ec.europa.eu/page/eupl-text-11-12
+# *
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the Licence is distributed on an "AS IS" basis,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the Licence for the specific language governing permissions and limitations under the Licence.
+ -->
+
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+ <!-- issuer name -->
+ <entry key="lightToken.connector.request.issuer.name">specificCommunicationDefinitionConnectorRequest</entry>
+ <entry key="lightToken.connector.request.node.id">specificConnector</entry>
+
+ <!--secrets and algorithms for request consent token-->
+ <entry key="lightToken.connector.request.secret">mySecretConnectorRequest</entry>
+ <entry key="lightToken.connector.request.algorithm">SHA-256</entry>
+
+ <!-- issuer name -->
+ <entry key="lightToken.connector.response.issuer.name">specificCommunicationDefinitionConnectorResponse</entry>
+ <entry key="lightToken.connector.response.node.id">specificConnector</entry>
+
+ <!--secrets and algorithms for response consent token-->
+ <entry key="lightToken.connector.response.secret">mySecretConnectorResponse</entry>
+ <entry key="lightToken.connector.response.algorithm">SHA-256</entry>
+
+ <!--The value of incoming lightRequest maximum number characters allowed-->
+ <entry key="incoming.lightRequest.max.number.characters">65535</entry>
+</properties>
diff --git a/ms_specific_proxyservice/src/test/resources/config/eIDAS/specificCommunicationDefinitionProxyservice.xml b/ms_specific_proxyservice/src/test/resources/config/eIDAS/specificCommunicationDefinitionProxyservice.xml
new file mode 100644
index 00000000..c8caf16b
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/eIDAS/specificCommunicationDefinitionProxyservice.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+# Copyright (c) 2017 European Commission
+# Licensed under the EUPL, Version 1.2 or – as soon they will be
+# approved by the European Commission - subsequent versions of the
+# EUPL (the "Licence");
+# You may not use this work except in compliance with the Licence.
+# You may obtain a copy of the Licence at:
+# * https://joinup.ec.europa.eu/page/eupl-text-11-12
+# *
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the Licence is distributed on an "AS IS" basis,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the Licence for the specific language governing permissions and limitations under the Licence.
+ -->
+
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+ <entry key="distributedCommunicationMaps">true</entry>
+
+ <!-- issuer name -->
+ <entry key="lightToken.proxyservice.request.issuer.name">specificCommunicationDefinitionProxyserviceRequest</entry>
+ <entry key="lightToken.proxyservice.request.node.id">specificProxyService</entry>
+ <!--secrets and algorithms for request consent token-->
+ <entry key="lightToken.proxyservice.request.secret">mySecretProxyserviceRequest</entry>
+ <entry key="lightToken.proxyservice.request.algorithm">SHA-256</entry>
+
+ <!-- issuer name -->
+ <entry key="lightToken.proxyservice.response.issuer.name">specificCommunicationDefinitionProxyserviceResponse</entry>
+ <entry key="lightToken.proxyservice.response.node.id">specificProxyService</entry>
+ <!--secrets and algorithms for response consent token-->
+ <entry key="lightToken.proxyservice.response.secret">mySecretProxyserviceResponse</entry>
+ <entry key="lightToken.proxyservice.response.algorithm">SHA-256</entry>
+
+ <!--The value of incoming Light Response maximum number characters allowed-->
+ <entry key="incoming.lightResponse.max.number.characters">65535</entry>
+</properties>
diff --git a/ms_specific_proxyservice/src/test/resources/config/junit_config_1_springboot.properties b/ms_specific_proxyservice/src/test/resources/config/junit_config_1_springboot.properties
new file mode 100644
index 00000000..9f36c9d7
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/junit_config_1_springboot.properties
@@ -0,0 +1,123 @@
+## Set Spring-Boot profile-configuration to 2.3 style
+spring.config.use-legacy-processing=true
+
+## ApplicationServer configuration
+server.servlet.contextPath=/ms_proxyservice
+#server.port=7080
+
+app.build.artifactId=ms_proxyservice
+
+
+
+#############################################################################
+## SpringBoot Admin client
+spring.boot.admin.client.enabled=false
+
+#############################################################################
+## SpringBoot Actuator
+management.endpoints.web.exposure.include=health,info
+
+#############################################################################
+## Common parts of MS-speccific eIDAS application configuration
+
+eidas.ms.context.url.prefix=https://localhost/ms_proxy/
+eidas.ms.context.url.request.validation=false
+eidas.ms.core.configRootDir=file:./src/test/resources/config/
+eidas.ms.context.use.clustermode=true
+eidas.ms.core.logging.level.info.errorcodes=auth.21
+
+##Monitoring
+eidas.ms.monitoring.eIDASNode.metadata.url=
+
+
+##Specific logger configuration
+eidas.ms.technicallog.write.MDS.into.techlog=true
+eidas.ms.revisionlog.write.MDS.into.revisionlog=true
+eidas.ms.revisionlog.logIPAddressOfUser=true
+
+
+##Directory for static Web content
+eidas.ms.webcontent.static.directory=webcontent/
+eidas.ms.webcontent.templates=templates/
+eidas.ms.webcontent.properties=properties/messages
+
+
+## extended validation of pending-request Id's
+eidas.ms.core.pendingrequestid.maxlifetime=300
+eidas.ms.core.pendingrequestid.digist.algorithm=HmacSHA256
+eidas.ms.core.pendingrequestid.digist.secret=pendingReqIdSecret
+
+
+## HTTP-client defaults
+eidas.ms.client.http.connection.timeout.socket=15
+eidas.ms.client.http.connection.timeout.connection=15
+eidas.ms.client.http.connection.timeout.request=15
+
+
+## Common PVP2 S-Profile (SAML2) configuration
+eidas.ms.pvp2.metadata.organisation.name=JUnit
+eidas.ms.pvp2.metadata.organisation.friendyname=For testing with jUnit
+eidas.ms.pvp2.metadata.organisation.url=http://junit.test
+eidas.ms.pvp2.metadata.contact.givenname=Max
+eidas.ms.pvp2.metadata.contact.surname=Mustermann
+eidas.ms.pvp2.metadata.contact.email=max@junit.test
+
+##only for advanced config
+eidas.ms.configuration.pvp.scheme.validation=true
+eidas.ms.configuration.pvp.enable.entitycategories=false
+
+
+#############################################################################
+## MS-speccific eIDAS-Proxy-Service configuration
+eidas.ms.auth.eIDAS.proxy.attribute.mapping.config=./../../../../../basicConfig/ms-proxyservice/misc/idaAttributeMapping.json
+
+#### eIDAS ms-specific Proxy-Service configuration
+eidas.ms.auth.eIDAS.node_v2.proxy.entityId=ownSpecificProxy
+eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint=http://localhost/EidasNode
+eidas.ms.auth.eIDAS.node_v2.forward.method=POST
+
+# Mandate configuration
+eidas.ms.auth.eIDAS.proxy.mandates.enabled=false
+#eidas.ms.auth.eIDAS.proxy.mandates.profiles.natural.default=
+#eidas.ms.auth.eIDAS.proxy.mandates.profiles.legal.default=
+
+
+## special foreign eIDAS-Connector configuration
+#eidas.ms.connector.0.uniqueID=https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/metadata
+#eidas.ms.connector.0.countryCode=CC
+#eidas.ms.connector.0.mandates.enabled=false
+#eidas.ms.connector.0.mandates.natural=
+#eidas.ms.connector.0.mandates.legal=
+#eidas.ms.connector.0.auth.idaustria.entityId=
+
+
+## PVP2 S-Profile communication with ID Austria System
+# EntityId and optional metadata of ID Austria System
+eidas.ms.modules.idaustriaauth.idp.entityId=classpath:/data/idp_metadata_classpath_entity.xml
+#eidas.ms.modules.idaustriaauth.idp.metadataUrl=
+
+# SAML2 client configuration
+eidas.ms.modules.idaustriaauth.keystore.path=keys/junit_test.jks
+eidas.ms.modules.idaustriaauth.keystore.password=password
+eidas.ms.modules.idaustriaauth.keystore.type=jks
+
+eidas.ms.modules.idaustriaauth.metadata.sign.alias=meta
+eidas.ms.modules.idaustriaauth.metadata.sign.password=password
+eidas.ms.modules.idaustriaauth.request.sign.alias=sig
+eidas.ms.modules.idaustriaauth.request.sign.password=password
+eidas.ms.modules.idaustriaauth.response.encryption.alias=enc
+eidas.ms.modules.idaustriaauth.response.encryption.password=password
+
+eidas.ms.modules.idaustriaauth.truststore.path=keys/junit_test.jks
+eidas.ms.modules.idaustriaauth.truststore.password=password
+eidas.ms.modules.idaustriaauth.truststore.type=jks
+
+
+#############################################################################
+## advanced eIDAS attribute processing
+
+# BORIS attribute for eJustice
+eidas.ms.advanced.attributes.ejusticerole.mandate.profiles=MUST_BE_UPDATED
+eidas.ms.advanced.attributes.ejusticerole.mandate.mode=legal
+eidas.ms.advanced.attributes.ejusticerole.value.1=MUST_BE_UPDATED=VIP1
+
diff --git a/ms_specific_proxyservice/src/test/resources/config/keys/Metadata.pem b/ms_specific_proxyservice/src/test/resources/config/keys/Metadata.pem
new file mode 100644
index 00000000..b544c194
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/keys/Metadata.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC+jCCAeKgAwIBAgIEXjF+fTANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJB
+VDENMAsGA1UEBwwERUdJWjEOMAwGA1UECgwFalVuaXQxETAPBgNVBAMMCE1ldGFk
+YXRhMB4XDTIwMDEyOTEyNDU0OVoXDTI2MDEyODEyNDU0OVowPzELMAkGA1UEBhMC
+QVQxDTALBgNVBAcMBEVHSVoxDjAMBgNVBAoMBWpVbml0MREwDwYDVQQDDAhNZXRh
+ZGF0YTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK230G3dxNbNlSYA
+O5Kx/Js0aBAgxMt7q9m+dA35fK/dOvF/GjrqjWsMCnax+no9gLnq6x0gXiJclz6H
+rp/YDOfLrJjMpNL/r0FWT947vbnEj7eT8TdY5d6Yi8AZulZmjiCI5nbZh2zwrP4+
+WqRroLoPhXQj8mDyp26M4xHBBUhLMRc2HV4S+XH4uNZ/vTmb8vBg31XGHCY33gl7
+/KA54JNGxJdN8Dxv6yHYsm91ZfVrX39W0iYLUNhUCkolwuQmjDVfrExM8BTLIONb
+f+erJoCm3A9ghZyDYRQ/e69/UEUqDa6XOzykr88INkQscEiAXCDS+EBPMpKo+t3l
+PIA9r7kCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAh/2mg4S03bdZy1OVtEAudBT9
+YZb9OF34hxPtNbkB/V04wSIg1d4TBr5KDhV7CdiUOxPZzHpS8LUCgfGX306FB6NX
+zh/b67uTOPaE72AB4VIT/Np0fsM7k5WhG9k9NoprIGiqCz2lXcfpZiT+LtSO1vWS
+YI87wR9KOSWjcw/5i5qZIAJuwvLCQj5JtUsmrhHK75222J3TJf4dS/gfN4xfY2rW
+9vcXtH6//8WdWp/zx9V7Z1ZsDb8TDKtBCEGuFDgVeU5ScKtVq8qRoUKD3Ve76cZi
+purO3KrRrVAuZP2EfLkZdHEHqe8GPigNnZ5kTn8V2VJ3iRAQ73hpJRR98tFd0A==
+-----END CERTIFICATE-----
diff --git a/ms_specific_proxyservice/src/test/resources/config/keys/junit.jks b/ms_specific_proxyservice/src/test/resources/config/keys/junit.jks
new file mode 100644
index 00000000..59e6ad13
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/keys/junit.jks
Binary files differ
diff --git a/ms_specific_proxyservice/src/test/resources/config/keys/junit_test.jks b/ms_specific_proxyservice/src/test/resources/config/keys/junit_test.jks
new file mode 100644
index 00000000..ee6254a9
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/keys/junit_test.jks
Binary files differ
diff --git a/ms_specific_proxyservice/src/test/resources/config/keys/teststore.jks b/ms_specific_proxyservice/src/test/resources/config/keys/teststore.jks
new file mode 100644
index 00000000..fcc6400c
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/keys/teststore.jks
Binary files differ
diff --git a/ms_specific_proxyservice/src/test/resources/config/logback_config.xml b/ms_specific_proxyservice/src/test/resources/config/logback_config.xml
new file mode 100644
index 00000000..bb3de3e8
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/logback_config.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- For assistance related to logback-translator or configuration -->
+<!-- files in general, please contact the logback user mailing list -->
+<!-- at http://www.qos.ch/mailman/listinfo/logback-user -->
+<!-- -->
+<!-- For professional support please see -->
+<!-- http://www.qos.ch/shop/products/professionalSupport -->
+<!-- -->
+<configuration>
+ <appender name="EIDASNODE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender-->
+ <File>${catalina.base}/logs/eIDAS_node.log</File>
+ <encoder>
+ <pattern>%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n</pattern>
+ </encoder>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <maxIndex>9999</maxIndex>
+ <FileNamePattern>${catalina.base}/logs/eIDAS_node.log.%i</FileNamePattern>
+ </rollingPolicy>
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <MaxFileSize>10000KB</MaxFileSize>
+ </triggeringPolicy>
+ </appender>
+ <appender name="msnode" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender-->
+ <File>${catalina.base}/logs/eidas-ms-reversion.log</File>
+ <encoder>
+ <pattern>%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n</pattern>
+ </encoder>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <maxIndex>9999</maxIndex>
+ <FileNamePattern>${catalina.base}/logs/eidas-ms-reversion.log.%i</FileNamePattern>
+ </rollingPolicy>
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <MaxFileSize>10000KB</MaxFileSize>
+ </triggeringPolicy>
+ </appender>
+ <appender name="reversion" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender-->
+ <File>${catalina.base}/logs/eidas-ms-reversion.log</File>
+ <encoder>
+ <pattern>%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n</pattern>
+ </encoder>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <maxIndex>9999</maxIndex>
+ <FileNamePattern>${catalina.base}/logs/eidas-ms-reversion.log.%i</FileNamePattern>
+ </rollingPolicy>
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <MaxFileSize>10000KB</MaxFileSize>
+ </triggeringPolicy>
+ </appender>
+ <appender name="statistic" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender-->
+ <File>${catalina.base}/logs/eidas-ms-statistic.log</File>
+ <encoder>
+ <pattern>%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n</pattern>
+ </encoder>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <maxIndex>9999</maxIndex>
+ <FileNamePattern>${catalina.base}/logs/eidas-ms-statistic.log.%i</FileNamePattern>
+ </rollingPolicy>
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <MaxFileSize>10000KB</MaxFileSize>
+ </triggeringPolicy>
+ </appender>
+ <appender name="stdout" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender-->
+ <File>${catalina.base}/logs/console.log</File>
+ <encoder>
+ <pattern>%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n</pattern>
+ </encoder>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <maxIndex>9999</maxIndex>
+ <FileNamePattern>${catalina.base}/logs/console.log.%i</FileNamePattern>
+ </rollingPolicy>
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <MaxFileSize>10000KB</MaxFileSize>
+ </triggeringPolicy>
+ </appender>
+ <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%5p | %d{dd HH:mm:ss,SSS} | %20c | %10t | %m%n</pattern>
+ </encoder>
+ </appender>
+ <logger name="eu.eidas" additivity="false" level="info">
+ <appender-ref ref="EIDASNODE"/>
+ </logger>
+ <logger name="at.gv.egiz.eidas.specific" additivity="false" level="info">
+ <appender-ref ref="msnode"/>
+ </logger>
+ <logger name="at.gv.egiz.eidas.specific.core.logger.RevisionLogger" additivity="false" level="info">
+ <appender-ref ref="reversion"/>
+ </logger>
+ <logger name="at.gv.egiz.eidas.specific.core.logger.StatisticLogger" additivity="false" level="info">
+ <appender-ref ref="statistic"/>
+ </logger>
+ <root level="warn">
+ <appender-ref ref="stdout"/>
+ <appender-ref ref="console"/>
+ </root>
+</configuration>
diff --git a/ms_specific_proxyservice/src/test/resources/config/properties/messages.properties b/ms_specific_proxyservice/src/test/resources/config/properties/messages.properties
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/properties/messages.properties
diff --git a/ms_specific_proxyservice/src/test/resources/config/properties/messages_de.properties b/ms_specific_proxyservice/src/test/resources/config/properties/messages_de.properties
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/properties/messages_de.properties
diff --git a/ms_specific_proxyservice/src/test/resources/config/properties/messages_en.properties b/ms_specific_proxyservice/src/test/resources/config/properties/messages_en.properties
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/properties/messages_en.properties
diff --git a/ms_specific_proxyservice/src/test/resources/config/templates/eidas_node_forward.html b/ms_specific_proxyservice/src/test/resources/config/templates/eidas_node_forward.html
new file mode 100644
index 00000000..6dffa34b
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/templates/eidas_node_forward.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org"
+ xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+ layout:decorator="fragments/base"
+ th:with="lang=${#locale.language}" th:lang="${lang}">
+<head>
+ <script src="../webcontent/autocommit.js"
+ th:attr="src=@{/autocommit.js}"></script>
+</head>
+<body>
+ <noscript>
+ <p>
+ <strong>Note:</strong> Since your browser does not support
+ JavaScript, you must press the Continue button once to proceed.
+ </p>
+ </noscript>
+
+ <div id="alert">Your login is being processed. Thank you for
+ waiting.</div>
+
+ <form action="${endPoint}" method="post" target="_parent"
+ th:attr="action=@{${endPoint}}">
+ <div>
+ <input type="hidden" name="${tokenName}" value="${tokenValue}"
+ th:attr="value=${tokenValue},name=${tokenName}" />
+ </div>
+ <noscript>
+ <div>
+ <p>Your browser does not support JavaScript. Click the button to continuing the process .</p>
+ <input type="submit" value="Continue" />
+ </div>
+ </noscript>
+ </form>
+
+</body>
+</html> \ No newline at end of file
diff --git a/ms_specific_proxyservice/src/test/resources/config/templates/error.html b/ms_specific_proxyservice/src/test/resources/config/templates/error.html
new file mode 100644
index 00000000..21f589cd
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/templates/error.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html xmlns:th="http://www.thymeleaf.org"
+ xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+ layout:decorator="fragments/base"
+ th:with="lang=${#locale.language}" th:lang="${lang}">
+
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
+<link rel="stylesheet" href="../webcontent/css/css_error.css" th:href="@{/css/css_error.css}"/>
+
+<title th:text="#{gui.errorpage.msg.title}">An error arise ... </title>
+</head>
+
+<body>
+<div id="page">
+ <div id="page1" class="case selected-case" role="main">
+ <div class="hell" role="application">
+ <h2 class="OA_header" role="heading" th:text="#{gui.errorpage.msg.title}">Error Header</h2>
+
+ <div id="alert_area" class="hell" role="application">
+ <p th:text="#{gui.errorpage.msg.information}">Error Information</p>
+ <br/>
+ <p><b th:text="#{gui.errorpage.msg.errorcode}">Code :</b> <span th:text="${errorCode}"></span></p>
+ <p><b th:text="#{gui.errorpage.msg.errormsg}">Msg :</b> <span
+ th:text="${#messages.msgWithParams('__${errorCode}__', '__${errorParams}__')}"></span></p>
+ </div>
+ </div>
+
+ <div th:if="${timestamp}">
+ <p><b>Timestamp:</b> <span th:text="${timestamp}"></span></p>
+ </div>
+ <div th:if="${error}">
+ <p><b>Error:</b> <span th:text="${error}"></span></p>
+ </div>
+ <div th:if="${status}">
+ <p><b>Status:</b> <span th:text="${status}"></span></p>
+ </div>
+ <div th:if="${message}">
+ <p><b>Message:</b> <span th:text="${message}"></span></p>
+ </div>
+ <div th:if="${exception}">
+ <p><b>Exception:</b> <span th:text="${exception}"></span></p>
+ </div>
+ <div th:if="${trace}">
+ <p><b>Trace:</b> <span th:text="${trace}"></span></p>
+ </div>
+ <div th:if="${Stacktrace}">
+ <p><b>Stacktrace:</b> <span th:text="${stacktrace}"></span></p>
+ </div>
+
+ </div>
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/ms_specific_proxyservice/src/test/resources/config/templates/error_message.html b/ms_specific_proxyservice/src/test/resources/config/templates/error_message.html
new file mode 100644
index 00000000..caaf7136
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/templates/error_message.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html xmlns:th="http://www.thymeleaf.org"
+ xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+ layout:decorator="fragments/base"
+ th:with="lang=${#locale.language}" th:lang="${lang}">
+
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
+ <link rel="stylesheet" href="../webcontent/css/css_error.css" th:href="@{/css/css_error.css}" />
+
+ <title th:text="#{gui.errorpage.msg.title}">An error arise ... </title>
+</head>
+
+<body>
+ <div id="page">
+ <div id="page1" class="case selected-case" role="main">
+ <h2 class="OA_header" role="heading">Authentication error arise</h2>
+
+ <div class="hell" role="application" >
+ <h2 class="OA_header" role="heading" th:text="#{gui.errorpage.msg.title}">Error Header</h2>
+
+ <div id="alert_area" class="hell" role="application" >
+ <p th:text="#{gui.errorpage.msg.information}">Error Information</p>
+ <br/>
+ <p><b th:text="#{gui.errorpage.msg.errorcode}">Code :</b> <span th:text="${errorCode}"></span></p>
+ <p><b th:text="#{gui.errorpage.msg.errormsg}">Msg :</b > <span th:text="${#messages.msgWithParams('__${errorCode}__', '__${errorParams}__')}"></span></p>
+ </div>
+ <!-- errorMsg -->
+ </div>
+
+ <div th:if="${stacktrace}">
+ <p><b th:text="#{gui.errorpage.msg.stacktrace}">fullError</b> <span th:text="${stacktrace}"></span></p>
+ </div>
+
+ </div>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/ms_specific_proxyservice/src/test/resources/config/templates/pvp2_post_binding.html b/ms_specific_proxyservice/src/test/resources/config/templates/pvp2_post_binding.html
new file mode 100644
index 00000000..06b9b494
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/templates/pvp2_post_binding.html
@@ -0,0 +1,36 @@
+## ## Velocity Template for SAML 2 HTTP-POST binding ## ## Velocity
+##context may contain the following properties ## action - String - the
+##action URL for the form ## RelayState - String - the relay state for the
+##message ## SAMLRequest - String - the Base64 encoded SAML Request ##
+##SAMLResponse - String - the Base64 encoded SAML Response
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+ <script src="/autocommit.js"></script>
+</head>
+<body>
+ <noscript>
+ <p>
+ <strong>Note:</strong> Since your browser does not support
+ JavaScript, you must press the Continue button once to proceed.
+ </p>
+ </noscript>
+
+ <div id="alert">Your login is being processed. Thank you for
+ waiting.</div>
+
+ <form action="${action}" method="post" target="_parent">
+ <div>
+ #if($RelayState) <input type="hidden" name="RelayState" value="${RelayState}"/> #end
+ #if($SAMLRequest) <input type="hidden" name="SAMLRequest" value="${SAMLRequest}" /> #end
+ #if($SAMLResponse) <input type="hidden" name="SAMLResponse" value="${SAMLResponse}" /> #end
+ </div>
+ <noscript>
+ <div>
+ <input type="submit" value="Continue" />
+ </div>
+ </noscript>
+ </form>
+
+</body>
+</html> \ No newline at end of file
diff --git a/ms_specific_proxyservice/src/test/resources/config/webcontent/autocommit.js b/ms_specific_proxyservice/src/test/resources/config/webcontent/autocommit.js
new file mode 100644
index 00000000..d21a5651
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/webcontent/autocommit.js
@@ -0,0 +1,5 @@
+function autoCommmit() {
+ document.forms[0].submit();
+}
+
+document.addEventListener('DOMContentLoaded', autoCommmit); \ No newline at end of file
diff --git a/ms_specific_proxyservice/src/test/resources/config/webcontent/css/css_error.css b/ms_specific_proxyservice/src/test/resources/config/webcontent/css/css_error.css
new file mode 100644
index 00000000..d772df43
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/webcontent/css/css_error.css
@@ -0,0 +1,26 @@
+@charset "utf-8";
+ body {
+ padding-left: 5%;
+ background-color: #F9F9F9;
+ }
+ #page {
+ padding-top: 2%;
+ padding-right: 10%;
+ padding-left: 5%;
+ }
+
+ .OA_header {
+ font-size: 2.1em;
+ padding-top:1%;
+ margin-bottom: 1%;
+ margin-top: 1%;
+
+ }
+
+ #alert_area {
+ float:left;
+ width: 100%;
+ }
+
+
+
diff --git a/ms_specific_proxyservice/src/test/resources/config/webcontent/img/ajax-loader.gif b/ms_specific_proxyservice/src/test/resources/config/webcontent/img/ajax-loader.gif
new file mode 100644
index 00000000..f2a1bc0c
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/config/webcontent/img/ajax-loader.gif
Binary files differ
diff --git a/ms_specific_proxyservice/src/test/resources/data/Response_with_EID.xml b/ms_specific_proxyservice/src/test/resources/data/Response_with_EID.xml
new file mode 100644
index 00000000..cf37a235
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/data/Response_with_EID.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/ms_proxy/sp/idaustria/eidas/post" ID="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_602c3236bffaf71ac3ac88674e76ff9f" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0">
+ <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp/metadata</saml2:Issuer>
+ <saml2:Subject>
+ <saml2:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" NameQualifier="urn:publicid:gv.at:cdid+BF">QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:NameID>
+ <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
+ <saml2:SubjectConfirmationData InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" NotOnOrAfter="2014-03-05T06:44:51.017Z" Recipient="https://localhost/ms_proxy/sp/eidas/post"/>
+ </saml2:SubjectConfirmation>
+ </saml2:Subject>
+ <saml2:Conditions NotBefore="2014-03-05T06:39:51.017Z" NotOnOrAfter="2035-03-05T06:44:51.017Z">
+ <saml2:AudienceRestriction>
+ <saml2:Audience>https://localhost/ms_proxy/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</saml2:AuthnContextClassRef>
+ </saml2:AuthnContext>
+ </saml2:AuthnStatement>
+ <saml2:AttributeStatement>
+ <saml2:Attribute FriendlyName="PVP-VERSION" Name="urn:oid:1.2.40.0.10.2.1.1.261.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">2.2</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="EID-CITIZEN-QAA- EIDAS-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.108" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/high</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="EID-ISSUING-NATION" Name="urn:oid:1.2.40.0.10.2.1.1.261.32" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">AT</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="PRINCIPAL-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.20" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Mustermann</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Max</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="BIRTHDATE" Name="urn:oid:1.2.40.0.10.2.1.1.55" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1940-01-01</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="BPK" Name="urn:oid:1.2.40.0.10.2.1.1.149" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">AT+XX:QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:AttributeValue>
+ </saml2:Attribute>
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/ms_specific_proxyservice/src/test/resources/data/idp_metadata_classpath_entity.xml b/ms_specific_proxyservice/src/test/resources/data/idp_metadata_classpath_entity.xml
new file mode 100644
index 00000000..de565887
--- /dev/null
+++ b/ms_specific_proxyservice/src/test/resources/data/idp_metadata_classpath_entity.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<md:EntityDescriptor
+ xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+ ID="_1a48ec3432f2f3ba6222724a5b06f873"
+ entityID="classpath:/data/idp_metadata_classpath_entity.xml"
+ validUntil="2045-02-06T08:47:26.211Z">
+ <md:IDPSSODescriptor
+ WantAuthnRequestsSigned="true"
+ protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+ <md:KeyDescriptor use="signing">
+ <ds:KeyInfo
+ xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate>MIIDMzCCAhsCBFtIcPowDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
+ SVoxJDAiBgNVBAsMG2NlbnRyYWwgbmF0aW9uYWwgZUlEQVMgbm9kZTEaMBgGA1UEAwwRQXNzZXJ0
+ aW9uIHNpZ25pbmcwHhcNMTgwNzEzMDkyOTMwWhcNMjEwNDA3MDkyOTMwWjBeMQswCQYDVQQGEwJB
+ VDENMAsGA1UECgwERUdJWjEkMCIGA1UECwwbY2VudHJhbCBuYXRpb25hbCBlSURBUyBub2RlMRow
+ GAYDVQQDDBFBc3NlcnRpb24gc2lnbmluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ AJ5zDYxMPRcz6AHaev1tS46Tq8sdgbGFM56uxk6c7LmMDC+HTzNX/3Q5S/YwSzgL3ue5TSw1ltOf
+ yMXMZ6D0+buWWcsxGEkQ8M3adKRFdQrEwafzwTA7pguq5WiHOkr4qwR7dLMome9z5cc3LRcwdOPP
+ gq7ahb5jM3hRqc5xkMWIuvql0NFXPzlHrjDLwy5nIWPOhL5abhVt4YsXbpbjXxFSGkDEAZ32K3EU
+ LNBr9FSUmJfbrVX9AU2T+BKIwiqXP8e/3UJHgPHQ0l5ljWp5P6u5+tvM21o8sUM4eArRa8BkdRsP
+ C92GVuASSUz2ZJ3JhAK1cSM8bnvaZVLQtTvPMAcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAAp7z
+ TubWXW6YMpyLSvWBdZiiQ3X66XpSZLZJDIAkoPzEY0DSBp8I5YASIx4JTR5XJt+6MI9acgNIAYW8
+ DhtRwUMVaRWEtuCrfKhGLWm5KSxnhPcD3lzRZhY4ZcA7dUlirjf6hnqo2TFEmJ9fkM+rxwy1GkDD
+ 7j2YDSOFmSq9/Ud9/IbIfSnRu/lO0dh7iRrmg3y0Y/+plPxYmp4AHqehP11OchTz2FGGHVsSC2Vs
+ IVBQI6ANZYyOlicgfEEFHA06jP9OnA0EwEFr2P+di9caZg8vfibyzxMGeuf6CY0c0eLHokBCn2W8
+ vkzvWiER3pozRvCmXFjCVZfRjUunaJf2ow==
+ </ds:X509Certificate>
+ </ds:X509Data>
+ <ds:X509Data>
+ <ds:X509Certificate>MIIC+DCCAeCgAwIBAgIEXh7TbTANBgkqhkiG9w0BAQsFADA+MQswCQYDVQQGEwJB
+ VDENMAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxEDAOBgNVBAMMB3NpZ25p
+ bmcwHhcNMjAwMTE1MDg1NTA5WhcNMjkwMTE0MDg1NTA5WjA+MQswCQYDVQQGEwJB
+ VDENMAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxEDAOBgNVBAMMB3NpZ25p
+ bmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCUSiRjnDvPafZfhJ+L
+ 1wM86FKJX3VIAV/8TD9qJ6HOBkn5WwYfpheyCfRb6XVDyIGpO8qnMWAgC17Ngbmh
+ zj8d8HXNQ2l3uppMv24oUTfXyYhQfZWAghx0sTlRIx/ZmlnduJilx2S53Sa7ruJw
+ lQcBFXj9h9B8dtyegc86Sx6D9BumP1xU7+mEBk8Gv9rR5Khg0Y7qGfZWB0t4aikg
+ aupWveVwiGifOOSfR8czqIg9qUpMYfZiTEBTSRmN6sPiNWhd4J0GyAI9Rn5C9jz/
+ sSlQrxpN+4DXzsqSU5F6gzq3yRux6wyOzDlt2birf21VPQ9HIy4YCjZXwgDWG7AO
+ 821pAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADnwdaxUtQU6SIpYwIb2c0ljTmQi
+ 7ryUcUpNHtK0M0E5Mw5Ex8zwrWbNQZ2sUyc4r07M66iOIqHsYZUQlRYvVKHifDpA
+ r8TCgD7iGGdB3By8Ou0RaNW+03w1fwmi98CufbHCGvpv0o2KxlejoHZminNdQ79i
+ bN+01nhocezJQATEQlnwHLiQSjilXpZeLYDk8HbrcUXNRxezN4ChdH+uU54vf+Ux
+ qcj9QHcmBe1+BM8EXfqS1DbTwZl+NTCnh5OYl8fvIFSOHMBxwFrI4pyY0faxg9Uc
+ rCogn/oQ+mV1gnVUDaDhvvEnVGZQtrlt7heVId2BeNellVgsrcmdW8j4U9U=
+ </ds:X509Certificate>
+ </ds:X509Data>
+ <ds:X509Data>
+ <ds:X509Certificate>MIIBbjCCARSgAwIBAgIEXh7TNzAKBggqhkjOPQQDAjA/MQswCQYDVQQGEwJBVDEN
+ MAsGA1UECgwERUdJWjEOMAwGA1UECwwFalVuaXQxETAPBgNVBAMMCG1ldGFkYXRh
+ MB4XDTIwMDExNTA4NTQxNVoXDTMwMDExNDA4NTQxNVowPzELMAkGA1UEBhMCQVQx
+ DTALBgNVBAoMBEVHSVoxDjAMBgNVBAsMBWpVbml0MREwDwYDVQQDDAhtZXRhZGF0
+ YTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBdBkaxt31p++aZeP3SmlWITj9SY
+ O4McV2ccXFsH4X4QMHuKAMUvjxPm1kdU01eTOWdiQX0GpDIBspYMZh8ZKcwwCgYI
+ KoZIzj0EAwIDSAAwRQIhAJ3QKlk9cd90s+i8y62fvmGF6LtfNO+JvkWqDUBeQImn
+ AiA2KwFtzO7STAp9MEwQGe0vt0F8mO1ttrLE+rr6YxdwGA==
+ </ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
+ </md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient
+ </md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
+ </md:NameIDFormat>
+ <md:SingleSignOnService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
+ Location="https://vidp.gv.at/ms_connector/pvp/post" />
+ <md:SingleSignOnService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
+ Location="https://vidp.gv.at/ms_connector/pvp/redirect" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="BPK" Name="urn:oid:1.2.40.0.10.2.1.1.149"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="BIRTHDATE" Name="urn:oid:1.2.40.0.10.2.1.1.55"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="PRINCIPAL-NAME"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.20"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-CCS-URL" Name="urn:oid:1.2.40.0.10.2.1.1.261.64"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-ISSUING-NATION"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.32"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="PVP-VERSION" Name="urn:oid:1.2.40.0.10.2.1.1.261.10"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-SOURCE-PIN"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.36"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-SIGNER-CERTIFICATE"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.66"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-SECTOR-FOR-IDENTIFIER"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.34"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-SOURCE-PIN-TYPE"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.104"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-E-ID-TOKEN"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.39"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-IDENTITY-LINK"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.38"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-CITIZEN-QAA-EIDAS-LEVEL"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.108"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ <saml2:Attribute
+ xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+ FriendlyName="EID-IDENTITY-STATUS-LEVEL"
+ Name="urn:oid:1.2.40.0.10.2.1.1.261.109"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" />
+ </md:IDPSSODescriptor>
+</md:EntityDescriptor>