aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2018-06-26 11:06:20 +0200
committerThomas Lenz <thomas.lenz@egiz.gv.at>2018-06-26 11:06:20 +0200
commitae550884f5467f6ff6df23100686bc54e100d2d4 (patch)
treecb06420ee6a0399991fd97b2dec912872990a5a2
downloadNational_eIDAS_Gateway-ae550884f5467f6ff6df23100686bc54e100d2d4.tar.gz
National_eIDAS_Gateway-ae550884f5467f6ff6df23100686bc54e100d2d4.tar.bz2
National_eIDAS_Gateway-ae550884f5467f6ff6df23100686bc54e100d2d4.zip
initial commit
-rw-r--r--.gitignore12
-rw-r--r--connector/pom.xml98
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/MSSpecificeIDASNodeSpringResourceProvider.java28
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/MSeIDASNodeConstants.java53
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/SpringInitializer.java166
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/auth/AuthenticationManager.java38
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/builder/AuthenticationDataBuilder.java64
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/builder/PVPSubjectNameGenerator.java19
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/BasicConfigurationProvider.java114
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/PVPEndPointConfiguration.java68
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/PVPMetadataConfiguration.java240
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/ServiceProviderConfiguration.java105
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/controller/PVP2SProfileEndpoint.java59
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/gui/DefaultGUIBuilderImpl.java44
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/gui/GUIBuilderConfigurationFactory.java32
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/gui/StaticGuiBuilderConfiguration.java91
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/mapper/LoALevelMapper.java34
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/PVPEndPointCredentialProvider.java92
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/PVPMetadataConfigurationFactory.java28
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/PVPMetadataProvider.java93
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/StatusMessageProvider.java30
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java138
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/storage/TransactionStoreElement.java34
-rw-r--r--connector/src/main/java/at/gv/egiz/eidas/specific/connector/verification/MetadataSignatureVerificationFilter.java136
-rw-r--r--connector/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider1
-rw-r--r--connector/src/main/resources/applicationContext.xml33
-rw-r--r--connector/src/main/resources/config/default_config.properties1
-rw-r--r--connector/src/main/resources/specific_eIDAS_connector.beans.xml81
-rw-r--r--connector/src/main/webapp/WEB-INF/web.xml22
-rw-r--r--connector/src/main/webapp/index.html0
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/pom.xml124
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/Constants.java45
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationModulImpl.java52
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationSpringResourceProvider.java30
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASSignalServlet.java82
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java160
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java313
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/ReceiveAuthnResponseTask.java143
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider1
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml20
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml34
-rw-r--r--eidas_modules/pom.xml21
-rw-r--r--pom.xml155
43 files changed, 3134 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..16a0a262
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+bin
+gen
+target
+*~
+*.orig
+*.log
+.settings
+.project
+.classpath
+.directory
+.checkstyle
+/id/server/moa-id-frontend-resources/src/main/resources/mainGUI/version.txt
diff --git a/connector/pom.xml b/connector/pom.xml
new file mode 100644
index 00000000..a461ab79
--- /dev/null
+++ b/connector/pom.xml
@@ -0,0 +1,98 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>at.gv.egiz.eidas</groupId>
+ <artifactId>ms_specific</artifactId>
+ <version>1.x</version>
+ </parent>
+
+ <groupId>at.gv.egiz.eidas.ms_specific</groupId>
+ <artifactId>ms_specific_connector</artifactId>
+ <packaging>war</packaging>
+ <version>${egiz.eidas.version}</version>
+ <name>Connector Maven Webapp</name>
+ <url>http://maven.apache.org</url>
+
+ <dependencies>
+ <!-- Web application -->
+
+ <dependency>
+ <groupId>at.gv.egiz.components</groupId>
+ <artifactId>egiz-spring-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf_module_pvp2_idp</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>log4j-over-slf4j</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- Third party libs -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+
+ <!-- Testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <finalName>ms_connector</finalName>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+
+ <!-- enable co-existence of testng and junit -->
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <threadCount>1</threadCount>
+ <argLine>--add-modules java.xml.bind</argLine>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.surefire</groupId>
+ <artifactId>surefire-junit47</artifactId>
+ <version>${surefire.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+
+ </plugins>
+ </build>
+</project>
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/MSSpecificeIDASNodeSpringResourceProvider.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/MSSpecificeIDASNodeSpringResourceProvider.java
new file mode 100644
index 00000000..f64b6073
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/MSSpecificeIDASNodeSpringResourceProvider.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector;
+
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import at.gv.egiz.components.spring.api.SpringResourceProvider;
+
+public class MSSpecificeIDASNodeSpringResourceProvider implements SpringResourceProvider {
+
+ @Override
+ public Resource[] getResourcesToLoad() {
+ ClassPathResource mseIDASNode = new ClassPathResource("/specific_eIDAS_connector.beans.xml", MSSpecificeIDASNodeSpringResourceProvider.class);
+ return new Resource[] {mseIDASNode};
+ }
+
+ @Override
+ public String[] getPackagesToScan() {
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return "MS-specific eIDAS Node SpringResourceProvider";
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/MSeIDASNodeConstants.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/MSeIDASNodeConstants.java
new file mode 100644
index 00000000..97defade
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/MSeIDASNodeConstants.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector;
+
+import at.gv.egiz.eaaf.core.api.data.EAAFConfigConstants;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+
+public class MSeIDASNodeConstants {
+ //configuration properties
+ public static final String PROP_CONFIG_APPLICATION_PREFIX = "eidas.ms.";
+ public static final String PROP_CONFIG_APPLICATION_PUBLIC_URL_PREFIX = "context.url.prefix";
+
+ private static final String PROP_CONFIG_PVP2_PREFIX = "pvp2.";
+ public static final String PROP_CONFIG_PVP2_KEYSTORE_PATH = PROP_CONFIG_PVP2_PREFIX + "keystore.path";
+ public static final String PROP_CONFIG_PVP2_KEYSTORE_PASSWORD = PROP_CONFIG_PVP2_PREFIX + "keystore.password";
+ public static final String PROP_CONFIG_PVP2_KEY_METADATA_ALIAS = PROP_CONFIG_PVP2_PREFIX + "key.metadata.alias";
+ public static final String PROP_CONFIG_PVP2_KEY_METADATA_PASSWORD = PROP_CONFIG_PVP2_PREFIX + "key.metadata.password";
+ public static final String PROP_CONFIG_PVP2_KEY_SIGNING_ALIAS = PROP_CONFIG_PVP2_PREFIX + "key.signing.alias";
+ public static final String PROP_CONFIG_PVP2_KEY_SIGNING_PASSWORD = PROP_CONFIG_PVP2_PREFIX + "key.signing.password";
+ public static final String PROP_CONFIG_PVP2_METADATA_VALIDITY = PROP_CONFIG_PVP2_PREFIX + "metadata.validity";
+
+ public static final String PROP_CONFIG_SP_LIST_PREFIX = "sp.";
+ public static final String PROP_CONFIG_SP_UNIQUEIDENTIFIER = EAAFConfigConstants.SERVICE_UNIQUEIDENTIFIER;
+ public static final String PROP_CONFIG_SP_FRIENDLYNAME = "friendlyName";
+ public static final String PROP_CONFIG_SP_PVP2_METADATA_URL = "pvp2.metadata.url";
+ public static final String PROP_CONFIG_SP_PVP2_METADATA_TRUSTSTORE = "pvp2.metadata.truststore";
+ public static final String PROP_CONFIG_SP_PVP2_METADATA_TRUSTSTORE_PASSWORD = "pvp2.metadata.truststore.password";
+ public static final String PROP_CONFIG_SP_POLICY_ALLOWED_TARGETS = "policy.allowed.requested.targets";
+ public static final String PROP_CONFIG_SP_POLICY_BASEIDTRANSFER_RESTRICTION = "policy.hasBaseIdTransferRestriction";
+
+ public static final String PROP_CONFIG_PVP_SCHEME_VALIDATION = "configuration.pvp.scheme.validation";
+ public static final String PROP_CONFIG_PVP_ENABLE_ENTITYCATEGORIES = "configuration.pvp.enable.entitycategories";
+
+ //default values
+ public static final String POLICY_DEFAULT_ALLOWED_TARGETS =
+ EAAFConstants.URN_PREFIX_CDID.replaceAll(".", "\\.").replaceAll("+", "\\+") + ".*";
+ public static final int METADATA_SOCKED_TIMEOUT = 20 * 1000; //20 seconds metadata socked timeout
+ public static final int DEFAULT_PVP_METADATA_VALIDITY = 24; //24 hours
+
+ //application end-points
+ public static final String ENDPOINT_PVP_METADATA = "/pvp/metadata";
+ public static final String ENDPOINT_PVP_POST = "/pvp/post";
+ public static final String ENDPOINT_PVP_REDIRECT = "/pvp/redirect";
+
+
+ //paths and templates
+ public static final String CLASSPATH_TEMPLATE_DIR = "/templates/";
+
+ public static final String TEMPLATE_HTML_ERROR = "error.html";
+ public static final String TEMPLATE_HTML_PVP_POSTBINDING = "pvp2_post_binding.html";
+
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/SpringInitializer.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/SpringInitializer.java
new file mode 100644
index 00000000..d5c2632c
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/SpringInitializer.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector;
+
+import java.util.Arrays;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.web.WebApplicationInitializer;
+import org.springframework.web.context.ContextLoaderListener;
+import org.springframework.web.context.request.RequestContextListener;
+import org.springframework.web.context.support.GenericWebApplicationContext;
+import org.springframework.web.context.support.ServletContextResource;
+import org.springframework.web.servlet.DispatcherServlet;
+
+import at.gv.egiz.components.spring.api.SpringLoader;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EAAFDefaultSAML2Bootstrap;
+
+/**
+ * Web application initializer
+ *
+ * @author Thomas Lenz
+ */
+public class SpringInitializer implements WebApplicationInitializer {
+
+ private static final Logger log = LoggerFactory.getLogger(SpringInitializer.class);
+
+ private String[] rootServletContexts = null;
+ private String[] servletContexts = null;
+ private String[] activeProfiles = null;
+
+ public SpringInitializer() {
+ this.rootServletContexts = null;
+ this.servletContexts = new String[] {
+ "/applicationContext.xml",
+
+ };
+ this.activeProfiles = null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.springframework.web.WebApplicationInitializer#onStartup(javax.servlet.ServletContext)
+ */
+ @Override
+ public void onStartup(ServletContext servletContext) throws ServletException {
+ try {
+ log.info("=============== Loading Config Root Context! ===============");
+ ApplicationContext cfgRootContext =
+ new ClassPathXmlApplicationContext(new String[] {
+ "/applicationContext.xml"
+ });
+
+
+ log.info("=============== Loading Root Context! ===============");
+ GenericWebApplicationContext rootContext = new GenericWebApplicationContext();
+ rootContext.setServletContext(servletContext);
+ rootContext.setParent(cfgRootContext);
+
+// log.info("=============== Setting active profiles! ===============");
+// if (this.activeProfiles != null) {
+// for (String profile : this.activeProfiles) {
+// rootContext.getEnvironment().addActiveProfile(profile);
+// }
+// }
+
+ log.info("Spring-context was initialized with active profiles: " +
+ Arrays.asList(rootContext.getEnvironment().getActiveProfiles()));
+
+ log.info("=============== Loading Local Contexts! ===============");
+ XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(
+ rootContext);
+ if (rootServletContexts != null) {
+ for (String rootServletContext : rootServletContexts) {
+ log.debug("Loading: "+ rootServletContext);
+ xmlReader.loadBeanDefinitions(new ServletContextResource(
+ servletContext, rootServletContext));
+ }
+ }
+ // Manage the lifecycle of the root application context
+ servletContext.addListener(new ContextLoaderListener(rootContext));
+
+ // log.debug("Beans after logAMQP in {}", rootContext);
+ // dumpBeanDefinitions(rootContext);
+
+ log.info("=============== Loading SPI Context! ===============");
+ if (rootContext instanceof BeanDefinitionRegistry) {
+ log.debug("Loading modules and components");
+ SpringLoader.loadSpringServices(rootContext);
+
+ } else
+ log.warn("Failed to load external Spring since no BeanDefinitionRegistry");
+
+ log.trace("Beans after SPI in "+ rootContext);
+ dumpBeanDefinitions(rootContext);
+
+ log.debug("Loading servlet config in "+ rootContext);
+ if (servletContexts != null) {
+ for (String servletContextString : servletContexts)
+ xmlReader.loadBeanDefinitions(new ClassPathResource(servletContextString, SpringInitializer.class));
+
+ }
+
+ log.debug("Refreshing context "+ rootContext);
+ rootContext.refresh();
+
+ log.info("=============== Register Dispatcher Servlet! ===============");
+
+ log.trace("Final Beans in "+ rootContext);
+ dumpBeanDefinitions(rootContext);
+
+ log.info("Registering dispatcher configuration");
+ ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
+ if (dispatcher != null) {
+ dispatcher.setLoadOnStartup(1);
+ dispatcher.addMapping("/");
+ dispatcher.setAsyncSupported(true);
+
+ } else
+ log.error("Failed to register dispatcher server in servlet context!");
+
+
+ log.info("=============== Register RequestContextListener! ===============");
+ servletContext.addListener(new RequestContextListener());
+
+ //TODO: integrate message provider!!!!
+ //log.info(MOAIDMessageProvider.getInstance().getMessage("init.00", null));
+
+ log.info("Bootstrap openSAML .... ");
+ EAAFDefaultSAML2Bootstrap.bootstrap();
+
+ log.info("Initialization of MS-specific eIDAS-connector finished.");
+
+
+ } catch (Throwable e) {
+ log.error("MS-specific eIDAS-connector initialization FAILED!", e);
+
+ }
+
+ }
+
+ private void dumpBeanDefinitions(GenericApplicationContext context) {
+ log.trace("Registered Bean in context " + context.toString());
+
+ String[] registeredBeans = context.getBeanDefinitionNames();
+ for (String registeredBean : registeredBeans) {
+ BeanDefinition beanDefinition = context
+ .getBeanDefinition(registeredBean);
+ log.trace(registeredBean + " -> " + beanDefinition.getBeanClassName());
+
+ }
+
+ log.trace("Registered Bean in context --"+ context);
+ }
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/auth/AuthenticationManager.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/auth/AuthenticationManager.java
new file mode 100644
index 00000000..e41bad28
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/auth/AuthenticationManager.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.auth;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.slo.ISLOInformationContainer;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.impl.idp.auth.AbstractAuthenticationManager;
+import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
+
+@Service("AuthenticationManager")
+public class AuthenticationManager extends AbstractAuthenticationManager {
+ private static final Logger log = LoggerFactory.getLogger(AuthenticationManager.class);
+
+ @Override
+ public ISLOInformationContainer performSingleLogOut(HttpServletRequest httpReq, HttpServletResponse httpResp,
+ IRequest pendingReq, String internalSSOId) throws EAAFException {
+ throw new RuntimeException("Single LogOut is NOT supported by this implementation");
+
+ }
+
+ @Override
+ protected void populateExecutionContext(ExecutionContext executionContext,
+ RequestImpl pendingReq, HttpServletRequest httpReq)
+ throws EAAFException {
+ log.trace("No implementation-specific population of execution-context required ... ");
+
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/builder/AuthenticationDataBuilder.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/builder/AuthenticationDataBuilder.java
new file mode 100644
index 00000000..775e36f2
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/builder/AuthenticationDataBuilder.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.builder;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.w3c.dom.DOMException;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IAuthProcessDataContainer;
+import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFBuilderException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFParserException;
+import at.gv.egiz.eaaf.core.exceptions.XPathException;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.core.impl.idp.AuthenticationData;
+import at.gv.egiz.eaaf.core.impl.idp.auth.builder.AbstractAuthenticationDataBuilder;
+import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper;
+
+@Service("AuthenticationDataBuilder")
+public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder {
+ private static final Logger log = LoggerFactory.getLogger(AuthenticationDataBuilder.class);
+
+ @Override
+ public IAuthData buildAuthenticationData(IRequest pendingReq) throws EAAFAuthenticationException {
+
+ IAuthProcessDataContainer authProcessData = new AuthProcessDataWrapper(pendingReq.genericFullDataStorage());
+ AuthenticationData authData = new AuthenticationData();
+
+ try {
+ generateBasicAuthData(authData, pendingReq, authProcessData);
+
+ } catch (EAAFBuilderException | EAAFParserException | EAAFConfigurationException
+ | XPathException | DOMException e) {
+ log.warn("Can not build authentication data from auth. process information");
+ throw new EAAFAuthenticationException("TODO", new Object[]{},
+ "Can not build authentication data from auth. process information", e);
+
+ }
+
+
+
+
+ return null;
+ }
+
+ @Override
+ protected Pair<String, String> getEncryptedbPKFromPVPAttribute(IAuthProcessDataContainer arg0,
+ AuthenticationData arg1, ISPConfiguration arg2) throws EAAFBuilderException {
+ return null;
+
+ }
+
+ @Override
+ protected Pair<String, String> getbaseIDFromSZR(AuthenticationData arg0, String arg1, String arg2) {
+ return null;
+
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/builder/PVPSubjectNameGenerator.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/builder/PVPSubjectNameGenerator.java
new file mode 100644
index 00000000..d640539a
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/builder/PVPSubjectNameGenerator.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.builder;
+
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception;
+import at.gv.egiz.eaaf.modules.pvp2.idp.api.builder.ISubjectNameIdGenerator;
+
+public class PVPSubjectNameGenerator implements ISubjectNameIdGenerator {
+
+ @Override
+ public Pair<String, String> generateSubjectNameId(IAuthData authData, ISPConfiguration spConfig) throws PVP2Exception {
+ //TODO: maybe update
+ return Pair.newInstance(authData.getBPK(), authData.getBPKType());
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/BasicConfigurationProvider.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/BasicConfigurationProvider.java
new file mode 100644
index 00000000..b898dfef
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/BasicConfigurationProvider.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.config;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.impl.idp.conf.AbstractConfigurationImpl;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+import at.gv.egiz.eidas.specific.connector.MSeIDASNodeConstants;
+
+@Service("BasicMSSpecificNodeConfig")
+public class BasicConfigurationProvider extends AbstractConfigurationImpl{
+ private static final Logger log = LoggerFactory.getLogger(BasicConfigurationProvider.class);
+
+ private Map<String, ISPConfiguration> spConfigCache = new HashMap<String, ISPConfiguration>();
+
+ public BasicConfigurationProvider(String configPath) throws EAAFConfigurationException {
+ super(configPath);
+
+ }
+
+ @Override
+ public ISPConfiguration getServiceProviderConfiguration(String entityId) throws EAAFConfigurationException {
+ if (!spConfigCache.containsKey(entityId)) {
+ log.debug("SP: " + entityId + " is NOT cached. Starting load operation ... ");
+ Map<String, String> allSPs = getBasicMOAIDConfigurationWithPrefix(MSeIDASNodeConstants.PROP_CONFIG_SP_LIST_PREFIX);
+ for (String key : allSPs.keySet()) {
+ if (key.endsWith(MSeIDASNodeConstants.PROP_CONFIG_SP_UNIQUEIDENTIFIER) &&
+ allSPs.get(key).equals(entityId)) {
+ String listId = KeyValueUtils.getParentKey(key);
+ log.trace("Find SP configuration with list-Id: " + listId + ". Extracting configuration elements ... ");
+ Map<String, String> spConfig = KeyValueUtils.getSubSetWithPrefix(allSPs, listId + KeyValueUtils.KEY_DELIMITER);
+ spConfigCache.put(entityId,
+ new ServiceProviderConfiguration(spConfig, this));
+ break;
+ }
+ }
+
+ if (spConfigCache.containsKey(entityId))
+ log.info("SP: " + entityId + " is loaded. Continuing auth. process ... ");
+ else {
+ log.warn("SP: " + entityId + " is NOT found in configuration. Stopping auth. process ... ");
+ return null;
+
+ }
+
+ } else
+ log.trace("SP: " + entityId + " is already cached. Use configuration from there ... ");
+
+
+ return spConfigCache.get(entityId);
+ }
+
+ @Override
+ public <T> T getServiceProviderConfiguration(String entityId, Class<T> decorator) throws EAAFConfigurationException {
+ ISPConfiguration spConfig = getServiceProviderConfiguration(entityId);
+ if (spConfig != null && decorator != null) {
+ if (decorator.isInstance(spConfig))
+ return (T)spConfig;
+ else
+ log.error("SPConfig: " + spConfig.getClass().getName() + " is NOT instance of: " + decorator.getName());
+
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public String validateIDPURL(URL url) throws EAAFException {
+ log.trace("Validate requested URL: " + url);
+ String urlPrefixFromConfig = getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_APPLICATION_PUBLIC_URL_PREFIX);
+ if (StringUtils.isEmpty(urlPrefixFromConfig)) {
+ log.warn("Application config containts NO URL prefix");
+ throw new EAAFConfigurationException("Application config containts NO URL prefix");
+
+ }
+
+ //remove last slash
+ if (urlPrefixFromConfig.endsWith("/"))
+ urlPrefixFromConfig = urlPrefixFromConfig.substring(0, urlPrefixFromConfig.length()-1);
+
+ if (url != null && url.toExternalForm().startsWith(urlPrefixFromConfig))
+ return urlPrefixFromConfig;
+
+
+ log.info("URL: " + url + " does NOT match to allowed application prefix: " + urlPrefixFromConfig);
+ return null;
+ }
+
+ @Override
+ public String getApplicationSpecificKeyPrefix() {
+ return MSeIDASNodeConstants.PROP_CONFIG_APPLICATION_PREFIX;
+
+ }
+
+ @Override
+ protected String getBackupConfigPath() {
+ return null;
+
+ }
+
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/PVPEndPointConfiguration.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/PVPEndPointConfiguration.java
new file mode 100644
index 00000000..21e46e10
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/PVPEndPointConfiguration.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.config;
+
+import java.util.List;
+
+import org.opensaml.saml2.metadata.ContactPerson;
+import org.opensaml.saml2.metadata.Organization;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.modules.pvp2.api.IPVP2BasicConfiguration;
+import at.gv.egiz.eidas.specific.connector.MSeIDASNodeConstants;
+
+@Service("PVPEndPointConfiguration")
+public class PVPEndPointConfiguration implements IPVP2BasicConfiguration {
+ private static final Logger log = LoggerFactory.getLogger(PVPEndPointConfiguration.class);
+
+ @Autowired(required=true) IConfiguration basicConfiguration;
+
+ @Override
+ public String getIDPEntityId(String authURL) throws EAAFException {
+ return removePostFix(authURL) + MSeIDASNodeConstants.ENDPOINT_PVP_METADATA;
+
+ }
+
+ @Override
+ public String getIDPSSOPostService(String authURL) throws EAAFException {
+ return removePostFix(authURL) + MSeIDASNodeConstants.ENDPOINT_PVP_POST;
+
+ }
+
+ @Override
+ public String getIDPSSORedirectService(String authURL) throws EAAFException {
+ return removePostFix(authURL) + MSeIDASNodeConstants.ENDPOINT_PVP_REDIRECT;
+
+ }
+
+ @Override
+ public Object getIDPSSOSOAPService(String extractAuthURLFromRequest) throws EAAFException {
+ log.warn("PVP S-Profile End-Point does NOT support SOAP Binding");
+ return null;
+
+ }
+
+ @Override
+ public List<ContactPerson> getIDPContacts() throws EAAFException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Organization getIDPOrganisation() throws EAAFException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ private String removePostFix(String url) {
+ if (url != null && url.endsWith("/"))
+ return url.substring(0, url.length() - 1);
+ else
+ return url;
+ }
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/PVPMetadataConfiguration.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/PVPMetadataConfiguration.java
new file mode 100644
index 00000000..7d17baa1
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/PVPMetadataConfiguration.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.config;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.NameIDType;
+import org.opensaml.saml2.metadata.ContactPerson;
+import org.opensaml.saml2.metadata.Organization;
+import org.opensaml.saml2.metadata.RequestedAttribute;
+import org.opensaml.xml.security.credential.Credential;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.modules.pvp2.api.IPVP2BasicConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataBuilderConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PVPAttributeBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider;
+import at.gv.egiz.eidas.specific.connector.MSeIDASNodeConstants;
+
+public class PVPMetadataConfiguration implements IPVPMetadataBuilderConfiguration{
+ private static final Logger log = LoggerFactory.getLogger(PVPMetadataConfiguration.class);
+
+ private IConfiguration basicConfig;
+ private String authUrl;
+ private AbstractCredentialProvider pvpIDPCredentials;
+ private IPVP2BasicConfiguration pvpBasicConfig;
+
+ public PVPMetadataConfiguration(IConfiguration basicConfig, String authURL, IPVP2BasicConfiguration pvpBasicConfig, AbstractCredentialProvider pvpIDPCredentials) {
+ this.authUrl = authURL;
+ this.pvpIDPCredentials = pvpIDPCredentials;
+ this.basicConfig = basicConfig;
+ this.pvpBasicConfig = pvpBasicConfig;
+
+ }
+
+ @Override
+ public String getSPNameForLogging() {
+ return "PVP2 S-Profile IDP";
+ }
+
+ @Override
+ public int getMetadataValidUntil() {
+ return Integer.valueOf(basicConfig.getBasicConfiguration(
+ MSeIDASNodeConstants.PROP_CONFIG_PVP2_METADATA_VALIDITY,
+ String.valueOf(MSeIDASNodeConstants.DEFAULT_PVP_METADATA_VALIDITY)));
+
+ }
+
+ @Override
+ public boolean buildEntitiesDescriptorAsRootElement() {
+ return false;
+
+ }
+
+ @Override
+ public boolean buildIDPSSODescriptor() {
+ return true;
+
+ }
+
+ @Override
+ public boolean buildSPSSODescriptor() {
+ return false;
+
+ }
+
+ @Override
+ public String getEntityID() {
+ try {
+ return pvpBasicConfig.getIDPEntityId(authUrl);
+
+ } catch (EAAFException e) {
+ log.error("Can NOT build PVP metadata configuration.", e);
+ throw new RuntimeException("Can NOT build PVP metadata configuration.");
+
+ }
+
+ }
+
+ @Override
+ public String getEntityFriendlyName() {
+ return null;
+
+ }
+
+ @Override
+ public List<ContactPerson> getContactPersonInformation() {
+ try {
+ return pvpBasicConfig.getIDPContacts();
+
+ } catch (EAAFException e) {
+ log.error("Can NOT build PVP metadata configuration.", e);
+ throw new RuntimeException("Can NOT build PVP metadata configuration.");
+
+ }
+
+ }
+
+ @Override
+ public Organization getOrgansiationInformation() {
+ try {
+ return pvpBasicConfig.getIDPOrganisation();
+
+ } catch (EAAFException e) {
+ log.error("Can NOT build PVP metadata configuration.", e);
+ throw new RuntimeException("Can NOT build PVP metadata configuration.");
+
+ }
+ }
+
+ @Override
+ public Credential getMetadataSigningCredentials() throws CredentialsNotAvailableException {
+ return pvpIDPCredentials.getIDPMetaDataSigningCredential();
+
+ }
+
+ @Override
+ public Credential getRequestorResponseSigningCredentials() throws CredentialsNotAvailableException {
+ return pvpIDPCredentials.getIDPAssertionSigningCredential();
+
+ }
+
+ @Override
+ public Credential getEncryptionCredentials() throws CredentialsNotAvailableException {
+ return null;
+
+
+ }
+
+ @Override
+ public String getIDPWebSSOPostBindingURL() {
+ try {
+ return pvpBasicConfig.getIDPSSOPostService(authUrl);
+
+ } catch (EAAFException e) {
+ log.error("Can NOT build PVP metadata configuration.", e);
+ throw new RuntimeException("Can NOT build PVP metadata configuration.");
+
+ }
+
+ }
+
+ @Override
+ public String getIDPWebSSORedirectBindingURL() {
+ try {
+ return pvpBasicConfig.getIDPSSORedirectService(authUrl);
+
+ } catch (EAAFException e) {
+ log.error("Can NOT build PVP metadata configuration.", e);
+ throw new RuntimeException("Can NOT build PVP metadata configuration.");
+
+ }
+ }
+
+ @Override
+ public String getIDPSLOPostBindingURL() {
+ return null;
+
+ }
+
+ @Override
+ public String getIDPSLORedirectBindingURL() {
+ return null;
+
+ }
+
+ @Override
+ public String getSPAssertionConsumerServicePostBindingURL() {
+ return null;
+
+ }
+
+ @Override
+ public String getSPAssertionConsumerServiceRedirectBindingURL() {
+ return null;
+
+ }
+
+ @Override
+ public String getSPSLOPostBindingURL() {
+ return null;
+
+ }
+
+ @Override
+ public String getSPSLORedirectBindingURL() {
+ return null;
+
+ }
+
+ @Override
+ public String getSPSLOSOAPBindingURL() {
+ return null;
+
+ }
+
+ @Override
+ public List<Attribute> getIDPPossibleAttributes() {
+ return PVPAttributeBuilder.buildSupportedEmptyAttributes();
+
+ }
+
+ @Override
+ public List<String> getIDPPossibleNameITTypes() {
+ return Arrays.asList(NameIDType.PERSISTENT,
+ NameIDType.TRANSIENT,
+ NameIDType.UNSPECIFIED);
+ }
+
+ @Override
+ public List<RequestedAttribute> getSPRequiredAttributes() {
+ return null;
+
+ }
+
+ @Override
+ public List<String> getSPAllowedNameITTypes() {
+ return null;
+
+ }
+
+ @Override
+ public boolean wantAssertionSigned() {
+ return false;
+
+ }
+
+ @Override
+ public boolean wantAuthnRequestSigned() {
+ return true;
+
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/ServiceProviderConfiguration.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/ServiceProviderConfiguration.java
new file mode 100644
index 00000000..3d8a3bdd
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/config/ServiceProviderConfiguration.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.config;
+
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.impl.idp.conf.SPConfigurationImpl;
+import at.gv.egiz.eidas.specific.connector.MSeIDASNodeConstants;
+
+public class ServiceProviderConfiguration extends SPConfigurationImpl {
+ private static final long serialVersionUID = 1L;
+ private static final Logger log = LoggerFactory.getLogger(ServiceProviderConfiguration.class);
+
+ private String minimumLoA = EAAFConstants.EIDAS_QAA_HIGH;
+ private String bPKTargetIdentifier;
+
+ public ServiceProviderConfiguration(Map<String, String> spConfig, IConfiguration authConfig) {
+ super(spConfig, authConfig);
+
+ }
+
+ @Override
+ public boolean hasBaseIdInternalProcessingRestriction() {
+ return false;
+
+ }
+
+ @Override
+ public boolean hasBaseIdTransferRestriction() {
+ return isConfigurationValue(
+ MSeIDASNodeConstants.PROP_CONFIG_SP_POLICY_BASEIDTRANSFER_RESTRICTION,
+ true);
+
+ }
+
+ @Override
+ public String getMinimumLevelOfAssurence() {
+ return minimumLoA;
+
+ }
+
+
+ @Override
+ public String getAreaSpecificTargetIdentifier() {
+ return bPKTargetIdentifier;
+ }
+
+
+ @Override
+ public String getFriendlyName() {
+ return getConfigurationValue(
+ MSeIDASNodeConstants.PROP_CONFIG_SP_FRIENDLYNAME,
+ "NO FRIENDLYNAME SET");
+
+ }
+
+ /**
+ * Set the minimum level of eIDAS authentication for this SP
+ * <br>
+ * <b>Default:</b> http://eidas.europa.eu/LoA/high or
+ *
+ * @param minimumLoA eIDAS LoA URI
+ */
+
+ public void setMinimumLoA(String minimumLoA) {
+ this.minimumLoA = minimumLoA;
+ }
+
+
+ /**
+ * Set the bPK Target for this service provider
+ *
+ * @param bPKTargetIdentifier
+ * @throws EAAFException If the bPKTargetIdentifier is NOT ALLOWED for this service provider
+ */
+ public void setbPKTargetIdentifier(String bPKTargetIdentifier) throws EAAFException {
+ String allowedTargetIdentifierRegExPattern = getConfigurationValue(
+ MSeIDASNodeConstants.PROP_CONFIG_SP_POLICY_ALLOWED_TARGETS,
+ MSeIDASNodeConstants.POLICY_DEFAULT_ALLOWED_TARGETS);
+ log.trace("Use bPK-target regex pattern: " + allowedTargetIdentifierRegExPattern);
+
+ Pattern p = Pattern.compile(allowedTargetIdentifierRegExPattern);
+ Matcher m = p.matcher(bPKTargetIdentifier);
+ if (m.matches()) {
+ log.debug("Requested bPK-target: " + bPKTargetIdentifier + " matches regex pattern");
+ this.bPKTargetIdentifier = bPKTargetIdentifier;
+
+ } else {
+ log.warn("Requested bPK-target: " + bPKTargetIdentifier + " does NOT match regex pattern.");
+ throw new EAAFException("TODO", new Object[] {bPKTargetIdentifier},
+ "Requested bPK-target: " + bPKTargetIdentifier + " does NOT match regex pattern.");
+
+ }
+
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/controller/PVP2SProfileEndpoint.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/controller/PVP2SProfileEndpoint.java
new file mode 100644
index 00000000..62092675
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/controller/PVP2SProfileEndpoint.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.controller;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.modules.pvp2.idp.impl.AbstractPVP2XProtocol;
+import at.gv.egiz.eaaf.modules.pvp2.idp.impl.PVPSProfilePendingRequest;
+import at.gv.egiz.eidas.specific.connector.MSeIDASNodeConstants;
+
+@Controller
+public class PVP2SProfileEndpoint extends AbstractPVP2XProtocol{
+
+ public static final String NAME = PVP2SProfileEndpoint.class.getName();
+ public static final String PROTOCOL_ID = "pvp2-s";
+
+ @RequestMapping(value = MSeIDASNodeConstants.ENDPOINT_PVP_METADATA, method = {RequestMethod.POST, RequestMethod.GET})
+ public void PVPMetadataRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException {
+ super.pvpMetadataRequest(req, resp);
+
+ }
+
+ @RequestMapping(value = MSeIDASNodeConstants.ENDPOINT_PVP_POST, method = {RequestMethod.POST})
+ public void PVPIDPPostRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException {
+ super.PVPIDPPostRequest(req, resp);
+
+ }
+
+ @RequestMapping(value = MSeIDASNodeConstants.ENDPOINT_PVP_REDIRECT, method = {RequestMethod.GET})
+ public void PVPIDPRedirecttRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException {
+ super.PVPIDPRedirecttRequest(req, resp);
+
+ }
+
+
+ @Override
+ public String getAuthProtocolIdentifier() {
+ return PROTOCOL_ID;
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ protected boolean childPreProcess(HttpServletRequest arg0, HttpServletResponse arg1, PVPSProfilePendingRequest arg2)
+ throws Throwable {
+ return false;
+ }
+
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/gui/DefaultGUIBuilderImpl.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/gui/DefaultGUIBuilderImpl.java
new file mode 100644
index 00000000..e423b09a
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/gui/DefaultGUIBuilderImpl.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.gui;
+
+import java.io.InputStream;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.GUIBuildException;
+import at.gv.egiz.eaaf.core.impl.gui.AbstractGUIFormBuilderImpl;
+
+@Service("DefaultGUIBuilderImpl")
+public class DefaultGUIBuilderImpl extends AbstractGUIFormBuilderImpl{
+ private static final Logger log = LoggerFactory.getLogger(DefaultGUIBuilderImpl.class);
+
+ private static final String CLASSPATH_HTMLTEMPLATES_DIR = "templates/";
+
+ public DefaultGUIBuilderImpl() throws GUIBuildException {
+ super();
+
+ }
+
+ @Override
+ protected InputStream getInternalTemplate(IGUIBuilderConfiguration config) throws GUIBuildException {
+ String viewName = config.getViewName();
+ log.debug("GUI template:" + viewName + " is not found in configuration directory. "
+ + " Load template from project library ... ");
+ String pathLocation = getInternalClasspathTemplateDir(config, CLASSPATH_HTMLTEMPLATES_DIR) + viewName;
+ try {
+ InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(pathLocation);
+ return is;
+
+ } catch (Exception e1) {
+ log.error("GUI template:" + pathLocation + " is NOT loadable from classpath!", e1);
+ throw new GUIBuildException("GUI template:" + pathLocation + " is NOT loadable from classpath!", e1);
+
+ }
+
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/gui/GUIBuilderConfigurationFactory.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/gui/GUIBuilderConfigurationFactory.java
new file mode 100644
index 00000000..8132c063
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/gui/GUIBuilderConfigurationFactory.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.gui;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfiguration;
+import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfigurationFactory;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eidas.specific.connector.MSeIDASNodeConstants;
+
+@Service("GUIBuilderConfigurationFactory")
+public class GUIBuilderConfigurationFactory implements IGUIBuilderConfigurationFactory {
+ @Autowired(required=true) private IConfiguration basicConfig;
+
+ @Override
+ public IGUIBuilderConfiguration getDefaultErrorGUI(String authURL) {
+ return new StaticGuiBuilderConfiguration(basicConfig, authURL, MSeIDASNodeConstants.TEMPLATE_HTML_ERROR, null);
+ }
+
+ @Override
+ public IGUIBuilderConfiguration getSPSpecificSAML2PostConfiguration(IRequest pendingReq, String viewName, URI configRootContextDir)
+ throws MalformedURLException {
+ return new StaticGuiBuilderConfiguration(basicConfig, pendingReq,MSeIDASNodeConstants.TEMPLATE_HTML_PVP_POSTBINDING , null);
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/gui/StaticGuiBuilderConfiguration.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/gui/StaticGuiBuilderConfiguration.java
new file mode 100644
index 00000000..8dd3c580
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/gui/StaticGuiBuilderConfiguration.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.gui;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.impl.gui.AbstractGUIFormBuilderConfiguration;
+import at.gv.egiz.eaaf.core.impl.utils.FileUtils;
+import at.gv.egiz.eidas.specific.connector.MSeIDASNodeConstants;
+
+public class StaticGuiBuilderConfiguration extends AbstractGUIFormBuilderConfiguration {
+ private static final Logger log = LoggerFactory.getLogger(StaticGuiBuilderConfiguration.class);
+
+ private IRequest pendingReq = null;
+ private IConfiguration basicConfig = null;
+
+ public StaticGuiBuilderConfiguration(IConfiguration basicConfig, String authURL, String viewName, String formSubmitEndpoint) {
+ super(authURL, viewName, formSubmitEndpoint);
+ this.basicConfig = basicConfig;
+ }
+
+ public StaticGuiBuilderConfiguration(IConfiguration basicConfig, IRequest pendingReq, String viewName, String formSubmitEndpoint) {
+ super(pendingReq.getAuthURL(), viewName, formSubmitEndpoint);
+ this.pendingReq = pendingReq;
+ this.basicConfig = basicConfig;
+
+ }
+
+ @Override
+ public String getClasspathTemplateDir() {
+ return MSeIDASNodeConstants.CLASSPATH_TEMPLATE_DIR;
+
+ }
+
+ @Override
+ public String getDefaultContentType() {
+ return null;
+
+ }
+
+ @Override
+ public InputStream getTemplate(String viewName) {
+ String templateURL = MSeIDASNodeConstants.CLASSPATH_TEMPLATE_DIR + viewName;
+ try {
+ String absURL = FileUtils.makeAbsoluteURL(templateURL, this.basicConfig.getConfigurationRootDirectory());
+ if (!absURL.startsWith("file:")) {
+ log.warn("Path to template looks like NOT absolut: " + absURL + ". Template loading FAILED");
+
+ } else {
+ log.debug("Load template URL for view: " + viewName + " from: " + absURL);
+ URI uri = new URL(absURL).toURI();
+ return new FileInputStream(new File(uri));
+
+ }
+
+
+ } catch (MalformedURLException | URISyntaxException | FileNotFoundException e) {
+ log.warn("Can can build filesytem path to template: " + templateURL, e);
+
+ }
+
+ return null;
+ }
+
+ @Override
+ protected Map<String, Object> getSpecificViewParameters() {
+ Map<String, Object> params = new HashMap<String, Object>();
+ if (pendingReq != null) {
+ params.put(PARAM_PENDINGREQUESTID, StringEscapeUtils.escapeHtml(pendingReq.getPendingRequestId()));
+
+ }
+
+ return params;
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/mapper/LoALevelMapper.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/mapper/LoALevelMapper.java
new file mode 100644
index 00000000..9432931e
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/mapper/LoALevelMapper.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.mapper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.data.ILoALevelMapper;
+
+@Service("LoALevelMapper")
+public class LoALevelMapper implements ILoALevelMapper{
+ private static final Logger log = LoggerFactory.getLogger(LoALevelMapper.class);
+
+ @Override
+ public String mapToSecClass(String LoA) {
+ log.info("Mapping to PVP SecClass is NOT supported");
+ return null;
+ }
+
+ @Override
+ public String mapToeIDASLoA(String LoA) {
+ if (LoA.startsWith(EAAFConstants.EIDAS_QAA_PREFIX))
+ return LoA;
+
+ else
+ log.info("Can NOT map '" + LoA + "' to eIDAS LoA");
+
+ return null;
+
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/PVPEndPointCredentialProvider.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/PVPEndPointCredentialProvider.java
new file mode 100644
index 00000000..cd86c79a
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/PVPEndPointCredentialProvider.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.provider;
+
+import java.net.MalformedURLException;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.impl.utils.FileUtils;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider;
+import at.gv.egiz.eidas.specific.connector.MSeIDASNodeConstants;
+
+public class PVPEndPointCredentialProvider extends AbstractCredentialProvider {
+ private static final Logger log = LoggerFactory.getLogger(PVPEndPointCredentialProvider.class);
+
+ @Autowired(required=true) IConfiguration basicConfiguration;
+
+ @Override
+ public String getFriendlyName() {
+ return "PVP2 S-Profile EndPoint";
+ }
+
+ @Override
+ public String getKeyStoreFilePath() throws EAAFException {
+ try {
+ String path = basicConfiguration.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_PVP2_KEYSTORE_PATH);
+ if (StringUtils.isEmpty(path)) {
+ log.error(getFriendlyName() + " | Path to keyStore is NULL or EMPTY");
+ throw new EAAFConfigurationException(getFriendlyName() + " | Path to keyStore is NULL or EMPTY");
+
+ }
+
+ return FileUtils.makeAbsoluteURL(
+ path,
+ basicConfiguration.getConfigurationRootDirectory());
+
+ } catch (MalformedURLException e) {
+ log.error(getFriendlyName() + " | Path to keyStore NOT valid.", e);
+ throw new EAAFConfigurationException(getFriendlyName() + " | Path to keyStore NOT valid.", e);
+
+ }
+
+ }
+
+ @Override
+ public String getKeyStorePassword() {
+ return basicConfiguration.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_PVP2_KEYSTORE_PASSWORD);
+
+ }
+
+ @Override
+ public String getMetadataKeyAlias() {
+ return basicConfiguration.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_PVP2_KEY_METADATA_ALIAS);
+ }
+
+ @Override
+ public String getMetadataKeyPassword() {
+ return basicConfiguration.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_PVP2_KEY_METADATA_PASSWORD);
+
+ }
+
+ @Override
+ public String getSignatureKeyAlias() {
+ return basicConfiguration.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_PVP2_KEY_SIGNING_ALIAS);
+
+ }
+
+ @Override
+ public String getSignatureKeyPassword() {
+ return basicConfiguration.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_PVP2_KEY_SIGNING_PASSWORD);
+
+ }
+
+ @Override
+ public String getEncryptionKeyAlias() {
+ return null;
+
+ }
+
+ @Override
+ public String getEncryptionKeyPassword() {
+ return null;
+
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/PVPMetadataConfigurationFactory.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/PVPMetadataConfigurationFactory.java
new file mode 100644
index 00000000..c5d2f29c
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/PVPMetadataConfigurationFactory.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.provider;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.api.IPVP2BasicConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataBuilderConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataConfigurationFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider;
+import at.gv.egiz.eidas.specific.connector.config.PVPMetadataConfiguration;
+
+@Service("PVPMetadataConfigurationFactory")
+public class PVPMetadataConfigurationFactory implements IPVPMetadataConfigurationFactory {
+
+ @Autowired private IConfiguration basicConfig;
+ @Autowired private IPVP2BasicConfiguration pvpBasicConfig;
+
+ @Override
+ public IPVPMetadataBuilderConfiguration generateMetadataBuilderConfiguration(String authURL,
+ AbstractCredentialProvider pvpIDPCredentials) {
+ return new PVPMetadataConfiguration(basicConfig, authURL, pvpBasicConfig, pvpIDPCredentials);
+
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/PVPMetadataProvider.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/PVPMetadataProvider.java
new file mode 100644
index 00000000..0edc5fcd
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/PVPMetadataProvider.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.provider;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.List;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.params.HttpClientParams;
+import org.opensaml.saml2.metadata.provider.MetadataProvider;
+import org.opensaml.xml.parse.BasicParserPool;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.AbstractChainingMetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.MetadataFilterChain;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.PVPEntityCategoryFilter;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.SchemaValidationFilter;
+import at.gv.egiz.eidas.specific.connector.MSeIDASNodeConstants;
+
+@Service("PVPMetadataProvider")
+public class PVPMetadataProvider extends AbstractChainingMetadataProvider{
+ private static final Logger log = LoggerFactory.getLogger(PVPMetadataProvider.class);
+
+ @Autowired(required=true) IConfiguration basicConfig;
+
+ @Override
+ protected String getMetadataURL(String entityId) throws EAAFConfigurationException {
+ ISPConfiguration spConfig = basicConfig.getServiceProviderConfiguration(entityId);
+ if (spConfig != null) {
+ return spConfig.getConfigurationValue(MSeIDASNodeConstants.PROP_CONFIG_SP_PVP2_METADATA_URL);
+
+ } else
+ log.info("No ServiceProvider with entityId: " + entityId + " in configuration.");
+
+ return null;
+ }
+
+ @Override
+ protected MetadataProvider createNewMetadataProvider(String entityId)
+ throws EAAFConfigurationException, IOException, CertificateException {
+ ISPConfiguration spConfig = basicConfig.getServiceProviderConfiguration(entityId);
+ if (spConfig != null) {
+ String metadataURL = spConfig.getConfigurationValue(MSeIDASNodeConstants.PROP_CONFIG_SP_PVP2_METADATA_URL);
+ String trustStoreUrl = spConfig.getConfigurationValue(MSeIDASNodeConstants.PROP_CONFIG_SP_PVP2_METADATA_TRUSTSTORE);
+ return createNewSimpleMetadataProvider(metadataURL,
+ buildMetadataFilterChain(spConfig, metadataURL, trustStoreUrl),
+ spConfig.getConfigurationValue(MSeIDASNodeConstants.PROP_CONFIG_SP_UNIQUEIDENTIFIER),
+ getTimer(),
+ new BasicParserPool(),
+ createHttpClient(metadataURL));
+
+ } else
+ log.info("No ServiceProvider with entityId: " + entityId + " in configuration.");
+
+ return null;
+ }
+
+ @Override
+ protected List<String> getAllMetadataURLsFromConfiguration() throws EAAFConfigurationException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ private HttpClient createHttpClient(String metadataURL) {
+ HttpClient httpClient = new HttpClient();
+ HttpClientParams httpClientParams = new HttpClientParams();
+ httpClientParams.setSoTimeout(MSeIDASNodeConstants.METADATA_SOCKED_TIMEOUT);
+ httpClient.setParams(httpClientParams);
+ return httpClient;
+
+ }
+
+ private MetadataFilterChain buildMetadataFilterChain(ISPConfiguration oaParam, String metadataURL, String trustStoreUrl) throws CertificateException{
+ MetadataFilterChain filterChain = new MetadataFilterChain();
+ filterChain.getFilters().add(new SchemaValidationFilter(
+ basicConfig.getBasicMOAIDConfigurationBoolean(MSeIDASNodeConstants.PROP_CONFIG_PVP_SCHEME_VALIDATION, true)));
+
+ //TODO: add signature validation filter
+
+
+ filterChain.getFilters().add(new PVPEntityCategoryFilter(
+ basicConfig.getBasicMOAIDConfigurationBoolean(MSeIDASNodeConstants.PROP_CONFIG_PVP_ENABLE_ENTITYCATEGORIES, true)));
+
+ return filterChain;
+ }
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/StatusMessageProvider.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/StatusMessageProvider.java
new file mode 100644
index 00000000..6e3f45cc
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/provider/StatusMessageProvider.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.provider;
+
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.api.IStatusMessager;
+
+@Service("StatusMessageProvider")
+public class StatusMessageProvider implements IStatusMessager {
+
+ @Override
+ public String getMessage(String messageId, Object[] parameters) {
+ return "NOT IMPLEMENTED YET";
+
+ }
+
+ @Override
+ public String getResponseErrorCode(Throwable throwable) {
+ return "NOT IMPLEMENTED YET";
+
+ }
+
+ @Override
+ public String mapInternalErrorToExternalError(String intErrorCode) {
+ return "NOT IMPLEMENTED YET";
+
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java
new file mode 100644
index 00000000..e4d02dae
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.storage;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException;
+
+@Service("SimpleInMemoryTransactionStorage")
+public class SimpleInMemoryTransactionStorage implements ITransactionStorage{
+ private static final Logger log = LoggerFactory.getLogger(SimpleInMemoryTransactionStorage.class);
+
+ private Map<String, TransactionStoreElement> storage = new ConcurrentHashMap<String, TransactionStoreElement>();
+
+ @Override
+ public void changeKey(String oldKey, String newKey, Object value) throws EAAFException {
+ if (containsKey(oldKey)) {
+
+
+ } else
+ throw new EAAFStorageException("No element in TransactionStorage with key: " + oldKey);
+
+ }
+
+ @Override
+ public List<String> clean(Date now, long dataTimeOut) {
+ List<String> result = new ArrayList<String>();
+ Iterator<String> iterator = storage.keySet().iterator();
+ while (iterator.hasNext()) {
+ String key = iterator.next();
+ synchronized (storage) {
+ if (storage.containsKey(key)) {
+ TransactionStoreElement element = storage.get(key);
+ if (now.getTime() - element.getCreated().getTime() > dataTimeOut)
+ result.add(key);
+ }
+ }
+ }
+
+ return result;
+
+ }
+
+ @Override
+ public boolean containsKey(String key) {
+ if (key != null)
+ return storage.containsKey(key);
+ else
+ return false;
+
+ }
+
+ @Override
+ public Object get(String key) throws EAAFException {
+ if (key != null && containsKey(key)) {
+ TransactionStoreElement element = storage.get(key);
+ return element.getData();
+
+ } else
+ return null;
+ }
+
+ @Override
+ public <T> T get(String key, Class<T> type) throws EAAFException {
+ return get(key, type, -1);
+
+ }
+
+ @Override
+ public <T> T get(String key, Class<T> type, long dataTimeOut) throws EAAFException {
+ if (key != null && containsKey(key)) {
+ TransactionStoreElement value = storage.get(key);
+
+ if (dataTimeOut > -1) {
+ long now = new Date().getTime();
+ if (now - value.getCreated().getTime() > dataTimeOut) {
+ log.info("Transaction-Data with key: " + key + " is out of time.");
+ throw new EAAFStorageException("Transaction-Data with key: " + key + " is out of time.");
+
+ }
+ }
+
+ if (type.isAssignableFrom(value.getData().getClass())) {
+ return (T) value.getData();
+
+ } else
+ log.warn("Can NOT cast '" + value.getClass() + "' to '" + type + "'");
+
+ }
+
+ return null;
+ }
+
+ @Override
+ public Object getRaw(String key) throws EAAFException {
+ return storage.get(key);
+
+ }
+
+ @Override
+ public void put(String key, Object value, int dataTimeOut) throws EAAFException {
+ TransactionStoreElement element = new TransactionStoreElement();
+ element.setKey(key);
+ element.setData(value);
+ storage.put(key, element);
+
+ }
+
+ @Override
+ public void putRaw(String key, Object value) throws EAAFException {
+ if (value instanceof TransactionStoreElement)
+ storage.put(((TransactionStoreElement) value).getKey(), (TransactionStoreElement) value);
+ else
+ log.info(value.getClass().getName() + " is NOT a RAW element of " + ITransactionStorage.class.getName());
+
+ }
+
+ @Override
+ public void remove(String key) {
+ if (containsKey(key)) {
+ log.debug("Remove element with key: " + key + " from " + ITransactionStorage.class.getName());
+ storage.remove(key);
+
+ }
+ }
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/storage/TransactionStoreElement.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/storage/TransactionStoreElement.java
new file mode 100644
index 00000000..a0224813
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/storage/TransactionStoreElement.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.storage;
+
+import java.util.Date;
+
+public class TransactionStoreElement {
+
+ private String key = null;
+ private Object data = null;
+ private Date created;
+
+ public String getKey() {
+ return key;
+ }
+ public void setKey(String key) {
+ this.key = key;
+ }
+ public Object getData() {
+ return data;
+ }
+ public void setData(Object data) {
+ this.data = data;
+ }
+ public Date getCreated() {
+ return created;
+ }
+ public void setCreated(Date created) {
+ this.created = created;
+ }
+
+
+
+}
diff --git a/connector/src/main/java/at/gv/egiz/eidas/specific/connector/verification/MetadataSignatureVerificationFilter.java b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/verification/MetadataSignatureVerificationFilter.java
new file mode 100644
index 00000000..ed88091b
--- /dev/null
+++ b/connector/src/main/java/at/gv/egiz/eidas/specific/connector/verification/MetadataSignatureVerificationFilter.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.connector.verification;
+
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.opensaml.common.SignableSAMLObject;
+import org.opensaml.saml2.metadata.EntitiesDescriptor;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.security.SAMLSignatureProfileValidator;
+import org.opensaml.xml.security.x509.BasicX509Credential;
+import org.opensaml.xml.signature.SignatureValidator;
+import org.opensaml.xml.validation.ValidationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils;
+import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.idp.exception.SAMLRequestNotSignedException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.AbstractMetadataSignatureFilter;
+
+public class MetadataSignatureVerificationFilter extends AbstractMetadataSignatureFilter{
+ private static final Logger log = LoggerFactory.getLogger(MetadataSignatureVerificationFilter.class);
+
+ private String metadataURL;
+ private List<BasicX509Credential> trustedCredential = new ArrayList<BasicX509Credential>();
+
+ public MetadataSignatureVerificationFilter(String trustStorePath, String trustStorePassword, String metadataURL)
+ throws PVP2MetadataException {
+ this.metadataURL = metadataURL;
+
+ log.trace("Initialize metadata signature-verification filter with truststore: " + trustStorePath + " ... ");
+ try {
+ KeyStore keyStore = KeyStoreUtils.loadKeyStore(trustStorePath, trustStorePassword);
+ if (keyStore != null) {
+ //load trusted certificates
+ Enumeration<String> aliases = keyStore.aliases();
+ while(aliases.hasMoreElements()) {
+ String el = aliases.nextElement();
+ log.trace("Process TrustStoreEntry: " + el);
+ if (keyStore.isCertificateEntry(el)) {
+ Certificate cert = keyStore.getCertificate(el);
+ if (cert != null && cert instanceof X509Certificate) {
+ BasicX509Credential trustedCert = new BasicX509Credential();
+ trustedCert.setEntityCertificate((X509Certificate) cert);
+ this.trustedCredential.add(trustedCert);
+ log.debug("Add cert: " + ((X509Certificate) cert).getSubjectDN() + " as trusted for metadata: " + metadataURL);
+
+ } else
+ log.info("Can not process entry: " + el + ". Reason: " + cert.toString());
+
+ }
+ }
+
+
+ }
+
+ } catch (KeyStoreException | IOException e) {
+ log.warn("Can not open trustStore: " + trustStorePath + " for metadata: " + metadataURL + " Reason: " + e.getMessage(), e);
+ throw new PVP2MetadataException("Can not open trustStore: " + trustStorePath + " for metadata", null, e);
+
+ }
+
+
+ }
+
+
+ @Override
+ protected void verify(EntityDescriptor desc) throws PVP2MetadataException {
+ try {
+ internalVerify(desc);
+
+ } catch (EAAFException e) {
+ log.info("Metadata verification FAILED for: " + metadataURL + " Reason: " +e.getMessage());
+ throw new PVP2MetadataException("Metadata verification FAILED for: " + metadataURL + " Reason: " +e.getMessage(), null, e);
+
+ }
+ }
+
+ @Override
+ protected void verify(EntitiesDescriptor desc) throws PVP2MetadataException {
+ throw new PVP2MetadataException("EntitiesDescritors are NOT supported", null);
+
+ }
+
+ @Override
+ protected void verify(EntityDescriptor entity, EntitiesDescriptor desc) throws PVP2MetadataException {
+ throw new PVP2MetadataException("EntitiesDescritors are NOT supported", null);
+
+ }
+
+ private void internalVerify(SignableSAMLObject signedElement)
+ throws EAAFException {
+ if (signedElement.getSignature() == null) {
+ throw new SAMLRequestNotSignedException();
+ }
+
+ try {
+ SAMLSignatureProfileValidator sigValidator = new SAMLSignatureProfileValidator();
+ sigValidator.validate(signedElement.getSignature());
+ } catch (ValidationException e) {
+ log.error("Failed to validate Signature", e);
+ throw new SAMLRequestNotSignedException(e);
+ }
+
+ boolean isTrusted = false;
+ for (BasicX509Credential cred : trustedCredential) {
+ SignatureValidator sigValidator = new SignatureValidator(cred);
+ try {
+ sigValidator.validate(signedElement.getSignature());
+ isTrusted = true;
+
+ } catch (ValidationException e) {
+ log.info("Failed to verfiy Signature with cert: " + cred.getEntityCertificate().getSubjectDN()
+ + " Reason: " + e.getMessage());
+
+ }
+ }
+
+ if (!isTrusted) {
+ log.warn("PVP2 metadata: " + metadataURL + " are NOT trusted!");
+ throw new SAMLRequestNotSignedException();
+
+ }
+
+ }
+
+}
diff --git a/connector/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider b/connector/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
new file mode 100644
index 00000000..fafe72f5
--- /dev/null
+++ b/connector/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
@@ -0,0 +1 @@
+at.gv.egiz.eidas.specific.connector.MSSpecificeIDASNodeSpringResourceProvider \ No newline at end of file
diff --git a/connector/src/main/resources/applicationContext.xml b/connector/src/main/resources/applicationContext.xml
new file mode 100644
index 00000000..5ede0b7f
--- /dev/null
+++ b/connector/src/main/resources/applicationContext.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:mvc="http://www.springframework.org/schema/mvc"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/mvc
+ http://www.springframework.org/schema/mvc/spring-mvc.xsd
+ http://www.springframework.org/schema/tx
+ http://www.springframework.org/schema/tx/spring-tx.xsd
+ "
+>
+
+ <context:annotation-config />
+ <mvc:annotation-driven />
+
+ <mvc:default-servlet-handler/>
+
+<!-- <mvc:interceptors>
+ <bean class="at.gv.egovernment.moa.id.auth.servlet.interceptor.WebFrontEndSecurityInterceptor" />
+ <bean class="at.gv.egovernment.moa.id.auth.servlet.interceptor.UniqueSessionIdentifierInterceptor" />
+ </mvc:interceptors> -->
+
+ <bean id="BasicMSSpecificNodeConfig"
+ class="at.gv.egiz.eidas.specific.connector.config.BasicConfigurationProvider">
+ <constructor-arg value="#{systemProperties['eidas.ms.configuration']}"/>
+ </bean>
+
+</beans>
diff --git a/connector/src/main/resources/config/default_config.properties b/connector/src/main/resources/config/default_config.properties
new file mode 100644
index 00000000..9eb856b8
--- /dev/null
+++ b/connector/src/main/resources/config/default_config.properties
@@ -0,0 +1 @@
+eidas.ms.context.url.prefix=https://labda.iaik.tugraz.at:8443/ms_connector/ \ No newline at end of file
diff --git a/connector/src/main/resources/specific_eIDAS_connector.beans.xml b/connector/src/main/resources/specific_eIDAS_connector.beans.xml
new file mode 100644
index 00000000..1e61d0d6
--- /dev/null
+++ b/connector/src/main/resources/specific_eIDAS_connector.beans.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xmlns:mvc="http://www.springframework.org/schema/mvc"
+ xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
+ http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
+
+ <context:annotation-config />
+ <mvc:annotation-driven />
+ <mvc:default-servlet-handler/>
+
+ <bean id="SimpleInMemoryTransactionStorage"
+ class="at.gv.egiz.eidas.specific.connector.storage.SimpleInMemoryTransactionStorage" />
+
+ <bean id="AuthenticationManager"
+ class="at.gv.egiz.eidas.specific.connector.auth.AuthenticationManager" />
+
+ <bean id="AuthenticationDataBuilder"
+ class="at.gv.egiz.eidas.specific.connector.builder.AuthenticationDataBuilder" />
+
+ <bean id="PVPEndPointConfiguration"
+ class="at.gv.egiz.eidas.specific.connector.config.PVPEndPointConfiguration"/>
+
+ <bean id="PVPEndPointCredentialProvider"
+ class="at.gv.egiz.eidas.specific.connector.provider.PVPEndPointCredentialProvider" />
+
+ <bean id="PVPMetadataConfigurationFactory"
+ class="at.gv.egiz.eidas.specific.connector.provider.PVPMetadataConfigurationFactory" />
+
+ <bean id="PVP2XProtocol"
+ class="at.gv.egiz.eidas.specific.connector.controller.PVP2SProfileEndpoint">
+ <property name="pvpIDPCredentials">
+ <ref bean="PVPEndPointCredentialProvider" />
+ </property>
+ </bean>
+
+ <bean id="pvpMetadataService"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.MetadataAction">
+ <property name="pvpIDPCredentials">
+ <ref bean="PVPEndPointCredentialProvider" />
+ </property>
+ </bean>
+
+ <bean id="PVPAuthenticationRequestAction"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.AuthenticationAction">
+ <property name="pvpIDPCredentials">
+ <ref bean="PVPEndPointCredentialProvider" />
+ </property>
+ </bean>
+
+ <bean id="PVPMetadataProvider"
+ class="at.gv.egiz.eidas.specific.connector.provider.PVPMetadataProvider" />
+
+ <bean id="PVPSubjectNameGenerator"
+ class="at.gv.egiz.eidas.specific.connector.builder.PVPSubjectNameGenerator"/>
+
+ <bean id="LoALevelMapper"
+ class="at.gv.egiz.eidas.specific.connector.mapper.LoALevelMapper"/>
+
+ <bean id="GUIBuilderConfigurationFactory"
+ class="at.gv.egiz.eidas.specific.connector.gui.GUIBuilderConfigurationFactory" />
+
+ <bean id="DefaultGUIBuilderImpl"
+ class="at.gv.egiz.eidas.specific.connector.gui.DefaultGUIBuilderImpl"/>
+
+ <bean id="StatusMessageProvider"
+ class="at.gv.egiz.eidas.specific.connector.provider.StatusMessageProvider" />
+
+ <bean id="DummyRevisionLogger"
+ class="at.gv.egiz.eaaf.core.impl.logging.DummyRevisionsLogger" />
+
+ <bean id="DummyStatisticLogger"
+ class="at.gv.egiz.eaaf.core.impl.logging.DummyStatisticLogger" />
+
+</beans> \ No newline at end of file
diff --git a/connector/src/main/webapp/WEB-INF/web.xml b/connector/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000..d5425ad4
--- /dev/null
+++ b/connector/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+
+ <display-name>AT eIDAS connector</display-name>
+ <description>MS specific eIDAS connector to national eID infrastructure</description>
+
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ </welcome-file-list>
+
+ <session-config>
+ <session-timeout>5</session-timeout>
+ </session-config>
+
+ <error-page>
+ <error-code>500</error-code>
+ <location>/errorpage.jsp</location>
+ </error-page>
+
+</web-app>
diff --git a/connector/src/main/webapp/index.html b/connector/src/main/webapp/index.html
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/connector/src/main/webapp/index.html
diff --git a/eidas_modules/authmodule-eIDAS-v2/pom.xml b/eidas_modules/authmodule-eIDAS-v2/pom.xml
new file mode 100644
index 00000000..48a5a249
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/pom.xml
@@ -0,0 +1,124 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>at.gv.egiz.eidas.ms_specific</groupId>
+ <artifactId>modules</artifactId>
+ <version>1.x</version>
+ </parent>
+
+ <artifactId>authmodule-eIDAS-v2</artifactId>
+ <name>eIDAS v2 authentication module</name>
+ <version>${egiz.eidas.version}</version>
+ <description>eIDAS module based on eIDAS node reference implementation v2.x</description>
+
+ <properties>
+ <eidas-commons.version>2.0.0</eidas-commons.version>
+ <eidas-light-commons.version>2.0.0</eidas-light-commons.version>
+ <eidas-specific-communication-definition.version>2.0.0</eidas-specific-communication-definition.version>
+ </properties>
+
+ <profiles>
+ <profile>
+ <id>default</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <repositories>
+ <repository>
+ <id>egiz-commons</id>
+ <url>https://demo.egiz.gv.at/int-repo/</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ </repository>
+ </repositories>
+ </profile>
+ </profiles>
+
+ <dependencies>
+ <dependency>
+ <groupId>at.gv.egiz.components</groupId>
+ <artifactId>egiz-spring-api</artifactId>
+ </dependency>
+
+
+ <!-- eIDAS reference implemenation libs -->
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-commons</artifactId>
+ <version>${eidas-commons.version}</version>
+ <!--scope>provided</scope -->
+ <exclusions>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <artifactId>log4j-over-slf4j</artifactId>
+ <groupId>org.slf4j</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-light-commons</artifactId>
+ <version>${eidas-light-commons.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>eu.eidas</groupId>
+ <artifactId>eidas-specific-communication-definition</artifactId>
+ <version>${eidas-specific-communication-definition.version}</version>
+ </dependency>
+
+ <!-- other third party libs -->
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-text</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+
+ <!-- enable co-existence of testng and junit -->
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <threadCount>1</threadCount>
+ <argLine>--add-modules java.xml.bind</argLine>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.surefire</groupId>
+ <artifactId>surefire-junit47</artifactId>
+ <version>${surefire.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/Constants.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/Constants.java
new file mode 100644
index 00000000..de7d9100
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/Constants.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class Constants {
+
+ //configuration properties
+ public static final String CONIG_PROPS_EIDAS_PREFIX="auth.eIDAS";
+ public static final String CONIG_PROPS_EIDAS_NODE= CONIG_PROPS_EIDAS_PREFIX + ".node_v2";
+ public static final String CONIG_PROPS_EIDAS_NODE_COUNTRYCODE = CONIG_PROPS_EIDAS_NODE + ".countrycode";
+
+
+ //http endpoint descriptions
+ public static final String eIDAS_HTTP_ENDPOINT_SP_POST = "/eidas/light/sp/post";
+ public static final String eIDAS_HTTP_ENDPOINT_SP_REDIRECT = "/eidas/light/sp/redirect";
+ public static final String eIDAS_HTTP_ENDPOINT_IDP_COLLEAGUEREQUEST = "/eidas/light/ColleagueRequest";
+ public static final String eIDAS_HTTP_ENDPOINT_METADATA = "/eidas/light/metadata";
+
+ //eIDAS request parameters
+ public static final String eIDAS_REQ_NAMEID_FORMAT = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent";
+
+ //eIDAS attribute names
+ public static final String eIDAS_ATTR_PERSONALIDENTIFIER = "PersonIdentifier";
+ public static final String eIDAS_ATTR_DATEOFBIRTH = "DateOfBirth";
+ public static final String eIDAS_ATTR_CURRENTGIVENNAME = "FirstName";
+ public static final String eIDAS_ATTR_CURRENTFAMILYNAME = "FamilyName";
+ public static final String eIDAS_ATTR_LEGALPERSONIDENTIFIER = "LegalPersonIdentifier";
+ public static final String eIDAS_ATTR_LEGALNAME = "LegalName";
+
+ public static final List<URI> NATURALPERSONMINIMUMDATASETLIST = Collections.unmodifiableList(new ArrayList<URI>() {
+ private static final long serialVersionUID = 1L;
+ {
+ //TODO: find correct location of attribute definitions
+// add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_FAMILY_NAME.getNameUri());
+// add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_GIVEN_NAME.getNameUri());
+// add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.DATE_OF_BIRTH.getNameUri());
+// add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.PERSON_IDENTIFIER.getNameUri());
+ }
+ });
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationModulImpl.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationModulImpl.java
new file mode 100644
index 00000000..1ce2f949
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationModulImpl.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.gv.egovernment.moa.id.auth.modules.AuthModule;
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+
+/**
+ * @author tlenz
+ *
+ */
+public class eIDASAuthenticationModulImpl implements AuthModule {
+
+ private int priority = 1;
+
+ @Override
+ public int getPriority() {
+ return priority;
+ }
+
+ /**
+ * Sets the priority of this module. Default value is {@code 0}.
+ * @param priority The priority.
+ */
+ public void setPriority(int priority) {
+ this.priority = priority;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#selectProcess(at.gv.egovernment.moa.id.process.api.ExecutionContext)
+ */
+ @Override
+ public String selectProcess(ExecutionContext context) {
+ if (StringUtils.isNotBlank((String) context.get("ccc")) ||
+ StringUtils.isNotBlank((String) context.get("CCC")))
+ return "eIDASAuthentication_v2";
+ else
+ return null;
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getProcessDefinitions()
+ */
+ @Override
+ public String[] getProcessDefinitions() {
+ return new String[] { "classpath:eIDAS.Authentication.process.xml" };
+ }
+
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationSpringResourceProvider.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationSpringResourceProvider.java
new file mode 100644
index 00000000..b491b8d8
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationSpringResourceProvider.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2;
+
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import at.gv.egiz.components.spring.api.SpringResourceProvider;
+
+public class eIDASAuthenticationSpringResourceProvider implements SpringResourceProvider {
+
+ @Override
+ public String getName() {
+ return "Auth. module for eIDAS Ref. Impl. v2.x";
+ }
+
+ @Override
+ public String[] getPackagesToScan() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Resource[] getResourcesToLoad() {
+ ClassPathResource eIDASAuthConfig = new ClassPathResource("/eidas_v2_auth.beans", eIDASAuthenticationSpringResourceProvider.class);
+
+ return new Resource[] {eIDASAuthConfig};
+ }
+
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASSignalServlet.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASSignalServlet.java
new file mode 100644
index 00000000..51d1bd0c
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASSignalServlet.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import at.gv.egovernment.moa.id.auth.servlet.AbstractProcessEngineSignalController;
+
+/**
+ * @author tlenz
+ *
+ */
+@Controller
+public class eIDASSignalServlet extends AbstractProcessEngineSignalController {
+
+ private static final Logger log = LoggerFactory.getLogger(eIDASSignalServlet.class);
+
+
+ public eIDASSignalServlet() {
+ super();
+ log.debug("Registering servlet " + getClass().getName() +
+ " with mappings '"+ Constants.eIDAS_HTTP_ENDPOINT_SP_POST +
+ "' and '"+ Constants.eIDAS_HTTP_ENDPOINT_SP_REDIRECT + "'.");
+
+ }
+
+ @RequestMapping(value = { Constants.eIDAS_HTTP_ENDPOINT_SP_POST,
+ Constants.eIDAS_HTTP_ENDPOINT_SP_REDIRECT
+ },
+ method = {RequestMethod.POST, RequestMethod.GET})
+ public void performCitizenCardAuthentication(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ signalProcessManagement(req, resp);
+ }
+
+ @Override
+ /**
+ * Protocol specific implementation to get the pending-requestID
+ * from http request object
+ *
+ * @param request The http Servlet-Request object
+ * @return The Pending-request id
+ *
+ */
+ public String getPendingRequestId(HttpServletRequest request) {
+ String sessionId = super.getPendingRequestId(request);
+
+ try {
+
+ // use SAML2 relayState
+ if (sessionId == null) {
+ log.trace("No transaction identifier from pendingReq. Search for SAML2 'RelayState' ...");
+ sessionId = StringEscapeUtils.escapeHtml4(request.getParameter("RelayState"));
+
+ if (StringUtils.isEmpty(sessionId))
+ log.info("NO transaction identifier found! Stopping process ....");
+ else
+ log.debug("Find transaction identifier in SAML2 'RelayState': " + sessionId);
+
+
+ } else
+ log.trace("Find transaction identifier from pendingReq.");
+
+ } catch (Exception e) {
+ log.warn("Unable to retrieve moa session id.", e);
+
+ }
+
+ return sessionId;
+ }
+
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java
new file mode 100644
index 00000000..dfd945c9
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.tasks;
+
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.joda.time.DateTime;
+import org.springframework.stereotype.Component;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants;
+import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
+import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
+import at.gv.egovernment.moa.id.auth.modules.eidas.Constants;
+import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASAttributeException;
+import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils;
+import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser;
+import at.gv.egovernment.moa.id.commons.api.data.IIdentityLink;
+import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException;
+import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+import at.gv.egovernment.moa.id.util.IdentityLinkReSigner;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.XPathUtils;
+import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
+
+/**
+ * @author tlenz
+ *
+ */
+@Component("CreateIdentityLinkTask")
+public class CreateIdentityLinkTask extends AbstractAuthServletTask {
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public void execute(ExecutionContext executionContext,
+ HttpServletRequest request, HttpServletResponse response)
+ throws TaskExecutionException {
+ try{
+ defaultTaskInitialization(request, executionContext);
+
+ //get eIDAS attributes from MOA-Session
+ ImmutableAttributeMap eIDASAttributes = moasession.getGenericDataFromSession(
+ AuthenticationSessionStorageConstants.eIDAS_ATTRIBUTELIST,
+ ImmutableAttributeMap.class);
+
+ IIdentityLink identityLink = null;
+
+ //connect SZR-Gateway
+ //TODO: implement SZR-Gateway communication!!!!
+ if(true) {
+
+ // create fake IdL
+ // - fetch IdL template from resources
+ InputStream s = CreateIdentityLinkTask.class.getResourceAsStream("/resources/xmldata/fakeIdL_IdL_template.xml");
+ Element idlTemplate = DOMUtils.parseXmlValidating(s);
+
+ identityLink = new IdentityLinkAssertionParser(idlTemplate).parseIdentityLink();
+
+ // replace data
+ Element idlassertion = identityLink.getSamlAssertion();
+
+ // - set fake baseID;
+ Node prIdentification = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH);
+
+
+ Object eIdentifier = eIDASAttributes.getFirstValue(
+ SAMLEngineUtils.getMapOfAllAvailableAttributes().get(
+ Constants.eIDAS_ATTR_PERSONALIDENTIFIER));
+ if (eIdentifier == null || !(eIdentifier instanceof String))
+ throw new eIDASAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ prIdentification.getFirstChild().setNodeValue((String) eIdentifier);
+
+ //build personal identifier which looks like a baseID
+// String fakeBaseID = new BPKBuilder().buildBPK(eIdentifier, "baseID");
+// Logger.info("Map eIDAS eIdentifier:" + eIdentifier + " to fake baseID:" + fakeBaseID);
+// prIdentification.getFirstChild().setNodeValue(fakeBaseID);
+
+ // - set last name
+ Node prFamilyName = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_FAMILY_NAME_XPATH);
+ Object familyName = eIDASAttributes.getFirstValue(
+ SAMLEngineUtils.getMapOfAllAvailableAttributes().get(
+ Constants.eIDAS_ATTR_CURRENTFAMILYNAME));
+ if (familyName == null || !(familyName instanceof String))
+ throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTFAMILYNAME);
+ prFamilyName.getFirstChild().setNodeValue((String) familyName);
+
+ // - set first name
+ Node prGivenName = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_GIVEN_NAME_XPATH);
+ Object givenName = eIDASAttributes.getFirstValue(
+ SAMLEngineUtils.getMapOfAllAvailableAttributes().get(
+ Constants.eIDAS_ATTR_CURRENTGIVENNAME));
+ if (givenName == null || !(givenName instanceof String))
+ throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTGIVENNAME);
+ prGivenName.getFirstChild().setNodeValue((String) givenName);
+
+ // - set date of birth
+ Node prDateOfBirth = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_DATE_OF_BIRTH_XPATH);
+ Object dateOfBirth = eIDASAttributes.getFirstValue(
+ SAMLEngineUtils.getMapOfAllAvailableAttributes().get(
+ Constants.eIDAS_ATTR_DATEOFBIRTH));
+ if (dateOfBirth == null || !(dateOfBirth instanceof DateTime))
+ throw new eIDASAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH);
+
+ String formatedDateOfBirth = new SimpleDateFormat("yyyy-MM-dd").format(((DateTime)dateOfBirth).toDate());
+ prDateOfBirth.getFirstChild().setNodeValue(formatedDateOfBirth);
+
+ identityLink = new IdentityLinkAssertionParser(idlassertion).parseIdentityLink();
+
+ //resign IDL
+ IdentityLinkReSigner identitylinkresigner = IdentityLinkReSigner.getInstance();
+ Element resignedilAssertion = identitylinkresigner.resignIdentityLink(identityLink.getSamlAssertion(), authConfig.getStorkFakeIdLResigningKey());
+ identityLink = new IdentityLinkAssertionParser(resignedilAssertion).parseIdentityLink();
+
+ } else {
+ //contact SZR Gateway
+ Logger.debug("Starting connecting SZR Gateway");
+
+ //TODO:!!!!!!
+
+ }
+
+ Logger.debug("SZR communication was successfull");
+
+ if (identityLink == null) {
+ Logger.error("SZR Gateway did not return an identity link.");
+ throw new MOAIDException("stork.10", null);
+ }
+
+ revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.AUTHPROCESS_PEPS_IDL_RECEIVED);
+ moasession.setForeigner(true);
+ moasession.setIdentityLink(identityLink);
+ moasession.setBkuURL("Not applicable (eIDASAuthentication)");
+
+ //store MOA-session to database
+ requestStoreage.storePendingRequest(pendingReq);
+
+ } catch (eIDASAttributeException e) {
+ throw new TaskExecutionException(pendingReq, "Minimum required eIDAS attributeset not found.", e);
+
+ } catch (MOAIDException | MOADatabaseException e) {
+ throw new TaskExecutionException(pendingReq, "IdentityLink generation for foreign person FAILED.", e);
+
+ } catch (Exception e) {
+ Logger.error("IdentityLink generation for foreign person FAILED.", e);
+ throw new TaskExecutionException(pendingReq, "IdentityLink generation for foreign person FAILED.", e);
+
+ }
+ }
+
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java
new file mode 100644
index 00000000..358b681e
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.tasks;
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.SingleSignOnService;
+import org.opensaml.saml2.metadata.provider.MetadataProviderException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import com.google.common.net.MediaType;
+
+import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.Constants;
+import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.frontend.velocity.VelocityProvider;
+import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
+import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
+import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters;
+import at.gv.egovernment.moa.id.commons.api.IRequest;
+import at.gv.egovernment.moa.id.commons.api.data.CPEPS;
+import at.gv.egovernment.moa.id.commons.api.data.StorkAttribute;
+import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException;
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+import eu.eidas.auth.commons.EidasStringUtil;
+import eu.eidas.auth.commons.attribute.AttributeDefinition;
+import eu.eidas.auth.commons.attribute.AttributeDefinition.Builder;
+import eu.eidas.auth.commons.light.impl.LightRequest;
+import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
+import eu.eidas.auth.commons.protocol.IRequestMessage;
+import eu.eidas.auth.commons.protocol.eidas.LevelOfAssurance;
+import eu.eidas.auth.commons.protocol.eidas.LevelOfAssuranceComparison;
+import eu.eidas.auth.commons.protocol.eidas.SpType;
+import eu.eidas.auth.commons.protocol.eidas.impl.EidasAuthenticationRequest;
+
+/**
+ * @author tlenz
+ *
+ */
+@Component("GenerateAuthnRequestTask")
+public class GenerateAuthnRequestTask extends AbstractAuthServletTask {
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public void execute(ExecutionContext executionContext,
+ HttpServletRequest request, HttpServletResponse response)
+ throws TaskExecutionException {
+
+ try{
+ //get service-provider configuration
+ IOAAuthParameters oaConfig = pendingReq.getOnlineApplicationConfiguration();
+
+ // get target and validate citizen countryCode
+ String citizenCountryCode = (String) executionContext.get(MOAIDAuthConstants.PARAM_CCC);
+
+ if (StringUtils.isEmpty(citizenCountryCode)) {
+ // illegal state; task should not have been executed without a selected country
+ throw new AuthenticationException("eIDAS.03", new Object[] { "" });
+
+ }
+ CPEPS cpeps = authConfig.getStorkConfig().getCPEPSWithFullName(citizenCountryCode);
+ if(null == cpeps) {
+ Logger.error("PEPS unknown for country: " + citizenCountryCode);
+ throw new AuthenticationException("eIDAS.04", new Object[] {citizenCountryCode});
+ }
+ Logger.debug("Found eIDaS Node/C-PEPS configuration for citizen of country: " + citizenCountryCode);
+
+
+ //TODO: load authnReq End-Point URL from configuration
+ SingleSignOnService authnReqEndpoint = null;
+
+
+ //TODO: switch to entityID and set new status codes
+// revisionsLogger.logEvent(oaConfig, pendingReq,
+// MOAIDEventConstants.AUTHPROCESS_PEPS_SELECTED,
+// metadataUrl);
+
+ // assemble requested attributes
+ Collection<StorkAttribute> attributesFromConfig = oaConfig.getRequestedSTORKAttributes();
+
+ // - prepare attribute list
+
+ // - fill container
+ List<AttributeDefinition<?>> reqAttrList = new ArrayList<AttributeDefinition<?>>();
+ //TODO: update requested attribute builder
+// for (StorkAttribute current : attributesFromConfig) {
+// AttributeDefinition<?> newAttribute = SAMLEngineUtils.getMapOfAllAvailableAttributes().get(current.getName());
+//
+// if (newAttribute == null) {
+// Logger.warn("eIDAS attribute with friendlyName:" + current.getName() + " is not supported.");
+//
+// } else {
+// boolean globallyMandatory = false;
+// for (StorkAttribute currentGlobalAttribute : authConfig.getStorkConfig().getStorkAttributes())
+// if (current.getName().equals(currentGlobalAttribute.getName())) {
+// globallyMandatory = BooleanUtils.isTrue(currentGlobalAttribute.getMandatory());
+// break;
+// }
+//
+// Builder<?> attrBuilder = AttributeDefinition.builder(newAttribute).required(current.getMandatory() || globallyMandatory);
+// reqAttrList.add(attrBuilder.build());
+//
+// }
+// }
+
+ //request
+// if (reqAttrList.isEmpty()) {
+// Logger.info("No attributes requested by OA:" + pendingReq.getOnlineApplicationConfiguration().getPublicURLPrefix()
+// + " --> Request attr:" + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + " by default");
+// AttributeDefinition<?> newAttribute = SAMLEngineUtils.getMapOfAllAvailableAttributes().get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+// Builder<?> attrBuilder = AttributeDefinition.builder(newAttribute).required(true);
+// reqAttrList.add(attrBuilder.build());
+//
+// }
+
+ //build requested attribute set
+ ImmutableAttributeMap reqAttrMap = new ImmutableAttributeMap.Builder().putAll(reqAttrList).build();
+
+ //build eIDAS AuthnRequest
+ LightRequest.Builder authnRequestBuilder = LightRequest.builder();
+
+ authnRequestBuilder.id(UUID.randomUUID().toString());
+ authnRequestBuilder.providerName(pendingReq.getAuthURL());
+ String issur = pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_METADATA;
+ authnRequestBuilder.issuer(issur);
+
+ //TODO:
+ //authnRequestBuilder.destination(authnReqEndpoint.getLocation());
+
+
+ authnRequestBuilder.nameIdFormat(Constants.eIDAS_REQ_NAMEID_FORMAT);
+
+ //set minimum required eIDAS LoA from OA config
+ String LoA = oaConfig.getQaaLevel();
+ //TODO:
+// if (MiscUtil.isNotEmpty(LoA))
+// authnRequestBuilder.levelOfAssurance(LevelOfAssurance.fromString(oaConfig.getQaaLevel()));
+// else
+ authnRequestBuilder.levelOfAssurance(LevelOfAssurance.HIGH.getValue());
+
+ //TODO: check if required
+ //authnRequestBuilder.levelOfAssuranceComparison(LevelOfAssuranceComparison.MINIMUM);
+
+
+ //set correct SPType for this online application
+ if (oaConfig.hasBaseIdTransferRestriction())
+ authnRequestBuilder.spType(SpType.PRIVATE.getValue());
+ else
+ authnRequestBuilder.spType(SpType.PUBLIC.getValue());
+
+
+ //TODO
+ //set service provider (eIDAS node) countryCode
+// authnRequestBuilder.serviceProviderCountryCode(
+// authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, "AT"));
+
+ //set citizen country code for foreign uses
+ authnRequestBuilder.citizenCountryCode(cpeps.getCountryCode());
+
+ //add requested attributes
+ authnRequestBuilder.requestedAttributes(reqAttrMap);
+
+
+ LightRequest lightAuthnReq = authnRequestBuilder.build();
+
+
+
+ //IRequestMessage authnRequest = engine.generateRequestMessage(authnRequestBuilder.build(), issur);
+
+ //encode AuthnRequest
+// byte[] token = authnRequest.getMessageBytes();
+// String SAMLRequest = EidasStringUtil.encodeToBase64(token);
+
+
+// if (SAMLConstants.SAML2_POST_BINDING_URI.equals(authnReqEndpoint.getBinding()))
+// buildPostBindingRequest(pendingReq, authnReqEndpoint, SAMLRequest, authnRequest, response);
+//
+// //TODO: redirect Binding is not completely implemented
+// //else if (SAMLConstants.SAML2_REDIRECT_BINDING_URI.equals(authnReqEndpoint.getBinding()))
+// //buildRedirecttBindingRequest(pendingReq, authnReqEndpoint, token, authnRequest, response);
+//
+// else {
+// Logger.error("eIDAS-node use an unsupported binding ("
+// + authnReqEndpoint.getBinding() + "). Request eIDAS node not possible.");
+// throw new MOAIDException("eIDAS.02", new Object[]{"eIDAS-node use an unsupported binding"});
+//
+// }
+
+
+
+// }catch (EIDASSAMLEngineException e){
+// throw new TaskExecutionException(pendingReq, "eIDAS AuthnRequest generation FAILED.",
+// new EIDASEngineException("eIDAS.00", new Object[]{e.getMessage()}, e));
+
+ } catch (MOAIDException e) {
+ throw new TaskExecutionException(pendingReq, "eIDAS AuthnRequest generation FAILED.", e);
+
+ } catch (Exception e) {
+ Logger.error("eIDAS AuthnRequest generation FAILED.", e);
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ }
+ }
+
+ /**
+ * Encode the eIDAS request with POST binding
+ *
+ * @param pendingReq
+ * @param authnReqEndpoint
+ * @param SAMLRequest
+ * @param authnRequest
+ * @param response
+ * @throws MOAIDException
+ */
+ private void buildPostBindingRequest(IRequest pendingReq, SingleSignOnService authnReqEndpoint,
+ String SAMLRequest, IRequestMessage authnRequest, HttpServletResponse response)
+ throws MOAIDException {
+ //send
+ try {
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/eidas_postbinding_template.vm");
+ VelocityContext context = new VelocityContext();
+
+ String actionType = "SAMLRequest";
+ context.put(actionType, SAMLRequest);
+ context.put("RelayState", pendingReq.getRequestID());
+ context.put("action", authnReqEndpoint.getLocation());
+
+ Logger.debug("Using SingleSignOnService url as action: " + authnReqEndpoint.getLocation());
+ Logger.debug("Encoded " + actionType + " original: " + SAMLRequest);
+
+ Logger.trace("Starting template merge");
+ StringWriter writer = new StringWriter();
+
+ Logger.trace("Doing template merge");
+ template.merge(context, writer);
+
+ Logger.trace("Template merge done");
+ Logger.trace("Sending html content: " + writer.getBuffer().toString());
+
+
+ byte[] content = writer.getBuffer().toString().getBytes("UTF-8");
+ response.setContentType(MediaType.HTML_UTF_8.toString());
+ response.setContentLength(content.length);
+ response.getOutputStream().write(content);
+
+ revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq,
+ MOAIDEventConstants.AUTHPROCESS_PEPS_REQUESTED,
+ authnRequest.getRequest().getId());
+
+ } catch (Exception e) {
+ Logger.error("Velocity general error: " + e.getMessage());
+ throw new MOAIDException("eIDAS.02", new Object[]{e.getMessage()}, e);
+
+ }
+
+ }
+
+ /**
+ * Select a SingleSignOnService endPoint from eIDAS node metadata.
+ * This endPoint receives the Authn. request
+ *
+ * @param idpEntity
+ * @return
+ */
+ private SingleSignOnService selectSingleSignOnServiceFromMetadata(EntityDescriptor idpEntity) {
+ //select SingleSignOn Service endpoint from IDP metadata
+ SingleSignOnService endpoint = null;
+ if (idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS) == null) {
+ return null;
+
+ }
+
+ for (SingleSignOnService sss :
+ idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS).getSingleSignOnServices()) {
+
+ // use POST binding as default if it exists
+ if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI))
+ endpoint = sss;
+
+ //TODO: redirect Binding is not completely implemented
+ // use Redirect binding as backup
+// else if ( sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)
+// && endpoint == null )
+// endpoint = sss;
+
+ }
+
+ return endpoint;
+ }
+
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/ReceiveAuthnResponseTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/ReceiveAuthnResponseTask.java
new file mode 100644
index 00000000..055c402f
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/ReceiveAuthnResponseTask.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.tasks;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.opensaml.saml2.core.StatusCode;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants;
+import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
+import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
+import at.gv.egovernment.moa.id.auth.modules.eidas.Constants;
+import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider;
+import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException;
+import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASResponseNotSuccessException;
+import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils;
+import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException;
+import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+import at.gv.egovernment.moa.id.protocols.eidas.validator.eIDASResponseValidator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+import eu.eidas.auth.commons.EidasStringUtil;
+import eu.eidas.auth.commons.protocol.IAuthenticationResponse;
+import eu.eidas.auth.engine.ProtocolEngineI;
+import eu.eidas.engine.exceptions.EIDASSAMLEngineException;
+
+@Component("ReceiveAuthnResponseTask")
+public class ReceiveAuthnResponseTask extends AbstractAuthServletTask {
+
+ @Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider;
+
+ @Override
+ public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) throws TaskExecutionException {
+
+ try{
+ //get SAML Response
+ String base64SamlToken = request.getParameter("SAMLResponse");
+ if (MiscUtil.isEmpty(base64SamlToken)) {
+ Logger.warn("No eIDAS SAMLReponse found in http request.");
+ throw new MOAIDException("HTTP request includes no eIDAS SAML-Response element.", null);
+
+ }
+
+ //get MOASession
+ defaultTaskInitialization(request, executionContext);
+
+ //decode SAML response
+ byte[] decSamlToken = EidasStringUtil.decodeBytesFromBase64(base64SamlToken);
+
+ //get eIDAS SAML-engine
+ ProtocolEngineI engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider);
+
+ //validate SAML token
+ IAuthenticationResponse samlResp = engine.unmarshallResponseAndValidate(decSamlToken,
+ request.getRemoteHost(),
+ Constants.CONFIG_PROPS_SKEWTIME_BEFORE,
+ Constants.CONFIG_PROPS_SKEWTIME_AFTER,
+ pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_METADATA);
+
+ if (samlResp.isEncrypted()) {
+ Logger.info("Received encrypted eIDAS SAML-Response.");
+ //TODO: check if additional decryption operation is required
+
+ }
+
+
+ //check response StatusCode
+ if (!samlResp.getStatusCode().equals(StatusCode.SUCCESS_URI)) {
+ Logger.info("Receice eIDAS Response with StatusCode:" + samlResp.getStatusCode()
+ + " Subcode:" + samlResp.getSubStatusCode() + " Msg:" + samlResp.getStatusMessage());
+ throw new EIDASResponseNotSuccessException("eIDAS.11", new Object[]{samlResp.getStatusMessage()});
+
+ }
+
+ // **********************************************************
+ // ******* MOA-ID specific response validation **********
+ // **********************************************************
+ String spCountry = authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, "AT");
+ eIDASResponseValidator.validateResponse(pendingReq, samlResp, spCountry);
+
+
+ // **********************************************************
+ // ******* Store resonse infos into session object **********
+ // **********************************************************
+
+ //update MOA-Session data with received information
+ Logger.debug("Store eIDAS response information into MOA-session.");
+
+ moasession.setQAALevel(samlResp.getLevelOfAssurance());
+
+ moasession.setGenericDataToSession(
+ AuthenticationSessionStorageConstants.eIDAS_ATTRIBUTELIST,
+ samlResp.getAttributes());
+
+ moasession.setGenericDataToSession(
+ AuthenticationSessionStorageConstants.eIDAS_RESPONSE,
+ decSamlToken);
+
+ //set issuer nation as PVP attribute into MOASession
+ moasession.setGenericDataToSession(PVPConstants.EID_ISSUING_NATION_NAME, samlResp.getCountry());
+
+ //store MOA-session to database
+ requestStoreage.storePendingRequest(pendingReq);
+
+ revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq,
+ MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED,
+ samlResp.getId());
+
+ } catch (MOAIDException e) {
+ throw new TaskExecutionException(pendingReq, "eIDAS Response processing FAILED.", e);
+
+ }catch (EIDASSAMLEngineException e) {
+ Logger.warn("eIDAS Response validation FAILED.", e);
+ Logger.debug("eIDAS response was: " + request.getParameter("SAMLResponse"));
+ revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq,
+ MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED_ERROR);
+ throw new TaskExecutionException(pendingReq, "eIDAS Response processing FAILED.",
+ new EIDASEngineException("eIDAS.09", new Object[]{e.getMessage()}, e));
+
+ } catch (MOADatabaseException e) {
+ revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq,
+ MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED_ERROR);
+ throw new TaskExecutionException(pendingReq, "eIDAS Response processing FAILED.",
+ new MOAIDException("init.04", new Object[]{""}, e));
+
+ } catch (Exception e) {
+ Logger.warn("eIDAS Response processing FAILED.", e);
+ revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq,
+ MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED_ERROR);
+ throw new TaskExecutionException(pendingReq, e.getMessage(),
+ new MOAIDException("eIDAS.10", new Object[]{e.getMessage()}, e));
+
+ }
+
+ }
+
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
new file mode 100644
index 00000000..f5af2dc4
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider
@@ -0,0 +1 @@
+at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.eIDASAuthenticationSpringResourceProvider \ No newline at end of file
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml
new file mode 100644
index 00000000..958c3391
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<pd:ProcessDefinition id="eIDASAuthentication_v2"
+ xmlns:pd="http://reference.e-government.gv.at/namespace/moa/process/definition/v1">
+
+
+ <pd:Task id="createAuthnRequest" class="GenerateAuthnRequestTask" />
+ <pd:Task id="receiveAuthnResponse" class="ReceiveAuthnResponseTask"
+ async="true" />
+ <pd:Task id="finalizeAuthentication" class="FinalizeAuthenticationTask" />
+ <pd:Task id="generateIdentityLink" class="CreateIdentityLinkTask" />
+
+ <pd:StartEvent id="start" />
+ <pd:Transition from="start" to="createAuthnRequest" />
+ <pd:Transition from="createAuthnRequest" to="receiveAuthnResponse" />
+ <pd:Transition from="receiveAuthnResponse" to="generateIdentityLink" />
+ <pd:Transition from="generateIdentityLink" to="finalizeAuthentication" />
+ <pd:Transition from="finalizeAuthentication" to="end" />
+ <pd:EndEvent id="end" />
+
+</pd:ProcessDefinition>
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml
new file mode 100644
index 00000000..1ad8cbeb
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
+
+ <context:annotation-config />
+
+ <bean id="eIDASAuthModule"
+ class="at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.eIDASAuthenticationModulImpl">
+ <property name="priority" value="2" />
+ </bean>
+
+ <bean id="eIDASSignalServlet"
+ class="at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.eIDASSignalServlet" />
+
+
+ <!-- Authentication Process Tasks -->
+ <bean id="GenerateAuthnRequestTask"
+ class="at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.tasks.GenerateAuthnRequestTask"
+ scope="prototype" />
+
+ <bean id="ReceiveAuthnResponseTask"
+ class="at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.tasks.ReceiveAuthnResponseTask"
+ scope="prototype" />
+
+ <bean id="CreateIdentityLinkTask"
+ class="at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.tasks.CreateIdentityLinkTask"
+ scope="prototype" />
+
+</beans> \ No newline at end of file
diff --git a/eidas_modules/pom.xml b/eidas_modules/pom.xml
new file mode 100644
index 00000000..2111af3a
--- /dev/null
+++ b/eidas_modules/pom.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>at.gv.egiz.eidas</groupId>
+ <artifactId>ms_specific</artifactId>
+ <version>1.x</version>
+ </parent>
+
+ <groupId>at.gv.egiz.eidas.ms_specific</groupId>
+ <artifactId>modules</artifactId>
+ <packaging>pom</packaging>
+
+ <name>Modules for MS specific eIDAS Node</name>
+
+ <modules>
+ <!-- <module>authmodule-eIDAS-v2</module> -->
+ </modules>
+
+
+</project> \ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 00000000..f6b400b9
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>at.gv.egiz.eidas</groupId>
+ <artifactId>ms_specific</artifactId>
+ <version>1.x</version>
+ <packaging>pom</packaging>
+
+ <name>MS specific eIDAS components</name>
+
+ <properties>
+ <!-- Project versions-->
+ <egiz.eidas.version>1.0.0-SNAPSHOT</egiz.eidas.version>
+
+
+ <!-- ===================================================================== -->
+ <egiz-spring-api>0.1</egiz-spring-api>
+ <eaaf-core.version>1.0.0-snapshot</eaaf-core.version>
+
+ <!-- <org.springframework.version>5.0.6.RELEASE</org.springframework.version> -->
+ <org.springframework.version>4.3.17.RELEASE</org.springframework.version>
+
+ <org.apache.commons-lang3.version>3.7</org.apache.commons-lang3.version>
+ <org.apache.commons-text.version>1.3</org.apache.commons-text.version>
+ <surefire.version>2.20.1</surefire.version>
+ <org.slf4j.version>1.7.25</org.slf4j.version>
+
+ </properties>
+
+ <profiles>
+ <profile>
+ <id>default</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ <property>
+ <name>default</name>
+ </property>
+ </activation>
+ <repositories>
+ <repository>
+ <id>egiz-commons</id>
+ <url>http://demo.egiz.gv.at/int-repo/</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ </repository>
+
+ </repositories>
+ </profile>
+ </profiles>
+
+ <modules>
+ <module>connector</module>
+ <module>eidas_modules</module>
+ </modules>
+
+ <dependencyManagement>
+ <dependencies>
+ <!-- Web application -->
+ <dependency>
+ <groupId>at.gv.egiz.components</groupId>
+ <artifactId>egiz-spring-api</artifactId>
+ <version>${egiz-spring-api}</version>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf-core</artifactId>
+ <version>${eaaf-core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf_module_pvp2_idp</artifactId>
+ <version>${eaaf-core.version}</version>
+ </dependency>
+
+
+ <!-- Third party libs -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ <version>${org.springframework.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${org.slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${org.slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>${org.apache.commons-lang3.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-text</artifactId>
+ <version>${org.apache.commons-text.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>3.0.1</version>
+ <scope>provided</scope>
+ </dependency>
+
+
+ <!-- Testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <finalName>ms-specific_eidas_node</finalName>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.7.0</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+
+ <!-- enable co-existence of testng and junit -->
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${surefire.version}</version>
+ <configuration>
+ <threadCount>1</threadCount>
+ <argLine>--add-modules java.xml.bind</argLine>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.surefire</groupId>
+ <artifactId>surefire-junit47</artifactId>
+ <version>${surefire.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project> \ No newline at end of file