diff options
Diffstat (limited to 'id/server')
161 files changed, 5374 insertions, 2840 deletions
diff --git a/id/server/auth-edu/pom.xml b/id/server/auth-edu/pom.xml index 43e87f2ab..4e01c6260 100644 --- a/id/server/auth-edu/pom.xml +++ b/id/server/auth-edu/pom.xml @@ -96,10 +96,6 @@ <type>pom</type> <exclusions> <exclusion> - <artifactId>iaik_pki_module</artifactId> - <groupId>iaik</groupId> - </exclusion> - <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> @@ -219,12 +215,12 @@ <!-- should be in the ext directory of the jre --> <scope>provided</scope> </dependency> - <dependency> +<!-- <dependency> <groupId>iaik.prod</groupId> <artifactId>iaik_ecc</artifactId> - <!-- should be in the ext directory of the jre --> + should be in the ext directory of the jre <scope>provided</scope> - </dependency> + </dependency> --> <dependency> <groupId>iaik.prod</groupId> <artifactId>iaik_Pkcs11Provider</artifactId> @@ -279,6 +275,11 @@ </exclusions> </dependency> <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-tx</artifactId> + <version>${org.springframework.version}</version> + </dependency> + <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </dependency> diff --git a/id/server/auth-final/pom.xml b/id/server/auth-final/pom.xml index 0c42c9deb..4f5f219a1 100644 --- a/id/server/auth-final/pom.xml +++ b/id/server/auth-final/pom.xml @@ -80,10 +80,6 @@ <type>pom</type> <exclusions> <exclusion> - <artifactId>iaik_pki_module</artifactId> - <groupId>iaik</groupId> - </exclusion> - <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> @@ -187,12 +183,12 @@ <!-- should be in the ext directory of the jre --> <scope>provided</scope> </dependency> - <dependency> +<!-- <dependency> <groupId>iaik.prod</groupId> <artifactId>iaik_ecc</artifactId> - <!-- should be in the ext directory of the jre --> + should be in the ext directory of the jre <scope>provided</scope> - </dependency> + </dependency> --> <dependency> <groupId>iaik.prod</groupId> <artifactId>iaik_Pkcs11Provider</artifactId> @@ -247,6 +243,11 @@ </exclusions> </dependency> <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-tx</artifactId> + <version>${org.springframework.version}</version> + </dependency> + <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </dependency> diff --git a/id/server/data/deploy/conf/moa-id/moa-id.properties b/id/server/data/deploy/conf/moa-id/moa-id.properties index 784f66602..bc1df5be8 100644 --- a/id/server/data/deploy/conf/moa-id/moa-id.properties +++ b/id/server/data/deploy/conf/moa-id/moa-id.properties @@ -79,12 +79,19 @@ moasession.hibernate.transaction.flush_before_completion=true moasession.hibernate.transaction.auto_close_session=true moasession.hibernate.show_sql=false moasession.hibernate.format_sql=true -moasession.hibernate.c3p0.acquire_increment=3 -moasession.hibernate.c3p0.idle_test_period=60 -moasession.hibernate.c3p0.timeout=60 -moasession.hibernate.c3p0.max_size=20 -moasession.hibernate.c3p0.max_statements=0 -moasession.hibernate.c3p0.min_size=3 + +moasession.dbcp.connectionProperties= +moasession.dbcp.initialSize=5 +moasession.dbcp.maxActive=20 +moasession.dbcp.maxIdle=8 +moasession.dbcp.minIdle=5 +moasession.dbcp.maxWaitMillis=-1 +moasession.dbcp.testOnBorrow=true +moasession.dbcp.testOnReturn=false +moasession.dbcp.testWhileIdle=false +moasession.dbcp.validationQuery=select 1 +moasession.jpaVendorAdapter.generateDdl=true + #Hibnerate configuration for MOA-ID 3.x configuration configuration.hibernate.dialect=org.hibernate.dialect.MySQLDialect @@ -122,14 +129,19 @@ advancedlogging.hibernate.current_session_context_class=thread advancedlogging.hibernate.transaction.auto_close_session=true advancedlogging.hibernate.show_sql=false advancedlogging.hibernate.format_sql=true -advancedlogging.hibernate.connection.provider_class=org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider -advancedlogging.hibernate.c3p0.acquire_increment=3 -advancedlogging.hibernate.c3p0.idle_test_period=60 -advancedlogging.hibernate.c3p0.timeout=300 -advancedlogging.hibernate.c3p0.max_size=20 -advancedlogging.hibernate.c3p0.max_statements=0 -advancedlogging.hibernate.c3p0.min_size=3 - +advancedlogging.hibernate.transaction.flush_before_completion=true + +advancedlogging.dbcp.connectionProperties= +advancedlogging.dbcp.initialSize=3 +advancedlogging.dbcp.maxActive=20 +advancedlogging.dbcp.maxIdle=8 +advancedlogging.dbcp.minIdle=3 +advancedlogging.dbcp.maxWaitMillis=-1 +advancedlogging.dbcp.testOnBorrow=true +advancedlogging.dbcp.testOnReturn=false +advancedlogging.dbcp.testWhileIdle=false +advancedlogging.dbcp.validationQuery=select 1 +advancedlogging.jpaVendorAdapter.generateDdl=true ################ Additonal eID-modul configuration #################################### ## This additional eID moduls add special functionality to MOA-ID-Auth. @@ -140,6 +152,9 @@ moa.id.protocols.eIDAS.samlengine.config.file=eIDAS/SamlEngine_basics.xml moa.id.protocols.eIDAS.samlengine.sign.config.file=eIDAS/SignModule.xml moa.id.protocols.eIDAS.samlengine.enc.config.file=eIDAS/EncryptModule.xml moa.id.protocols.eIDAS.metadata.validation.truststore=eIDAS_metadata +moa.id.protocols.eIDAS.node.country=Austria +moa.id.protocols.eIDAS.node.countrycode=AT +moa.id.protocols.eIDAS.node.LoA=http://eidas.europa.eu/LoA/high ### HBV Mandate-Service client module ### modules.elga_mandate.nameID.target=urn:publicid:gv.at:cdid+GH @@ -165,6 +180,12 @@ modules.federatedAuth.request.sign.password=password modules.federatedAuth.response.encryption.alias=pvp_assertion modules.federatedAuth.response.encryption.password=password +#Redis Settings, if Redis is used as a backend for session data. +#has to be enabled with the following parameter +#redis.active=true +redis.use-pool=true +redis.host-name=localhost +redis.port=6379 ################SZR Client configuration#################################### ## The SZR client is only required if MOA-ID-Auth should be diff --git a/id/server/doc/handbook/protocol/protocol.html b/id/server/doc/handbook/protocol/protocol.html index 58474b635..5a578a5aa 100644 --- a/id/server/doc/handbook/protocol/protocol.html +++ b/id/server/doc/handbook/protocol/protocol.html @@ -685,7 +685,11 @@ Redirect Binding</td> </tr> <tr> <td>1306</td> - <td>Generierung dereIDAS Metadaten fehlgeschlagen</td> + <td>Generierung der eIDAS Metadaten fehlgeschlagen</td> + </tr> + <tr> + <td>1307</td> + <td>Generierung der eIDAS Response fehlgeschlagen</td> </tr> <tr> <td>1399</td> diff --git a/id/server/idserverlib/pom.xml b/id/server/idserverlib/pom.xml index fb6ba1bc6..6c6353be0 100644 --- a/id/server/idserverlib/pom.xml +++ b/id/server/idserverlib/pom.xml @@ -85,11 +85,11 @@ </exclusion>
</exclusions>
</dependency>
- <dependency>
+ <!-- dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>${hibernate.version}</version>
- </dependency>
+ </dependency-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
@@ -205,6 +205,12 @@ <artifactId>unitils-core</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
<!-- <dependency>
<groupId>MOA</groupId>
<artifactId>moa-common</artifactId>
@@ -315,6 +321,13 @@ <scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>iaik.prod</groupId>
+ <artifactId>iaik_ixsil</artifactId>
+ <version>1.2.2.5</version>
+ <scope>test</scope>
+ </dependency>
+
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
@@ -386,7 +399,41 @@ <artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
-
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-tx</artifactId>
+ <version>${org.springframework.version}</version>
+ </dependency>
+
+
+ <!-- Redis -->
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-redis</artifactId>
+ <version>1.7.2.RELEASE</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-pool2</artifactId>
+ <version>2.4.2</version>
+ </dependency>
+ <dependency>
+ <groupId>redis.clients</groupId>
+ <artifactId>jedis</artifactId>
+ <version>2.8.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-core-asl</artifactId>
+ <version>1.9.13</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ <version>1.9.13</version>
+ </dependency>
</dependencies>
<build>
@@ -457,6 +504,9 @@ <goals>
<goal>jar</goal>
</goals>
+ <configuration>
+ <additionalparam>-Xdoclint:none</additionalparam>
+ </configuration>
</execution>
</executions>
</plugin>
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/DummyStatisticLogger.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/DummyStatisticLogger.java new file mode 100644 index 000000000..5a1b7205d --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/DummyStatisticLogger.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + *******************************************************************************/ +package at.gv.egovernment.moa.id.advancedlogging; + + +import org.springframework.stereotype.Service; + +import at.gv.egovernment.moa.id.commons.api.IRequest; +import at.gv.egovernment.moa.id.data.IAuthData; +import at.gv.egovernment.moa.logging.Logger; + +@Service("StatisticLogger") +public class DummyStatisticLogger implements IStatisticLogger{ + + @Override + public void logSuccessOperation(IRequest protocolRequest, + IAuthData authData, boolean isSSOSession) { + Logger.trace("Dummy-logSuccessOperation"); + } + + @Override + public void logErrorOperation(Throwable throwable) { + Logger.trace("Dummy-logErrorOperation"); + } + + @Override + public void logErrorOperation(Throwable throwable, IRequest errorRequest) { + Logger.trace("Dummy-logErrorOperation"); + }} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/IStatisticLogger.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/IStatisticLogger.java new file mode 100644 index 000000000..2d97d7258 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/IStatisticLogger.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + *******************************************************************************/ +package at.gv.egovernment.moa.id.advancedlogging; + +import at.gv.egovernment.moa.id.commons.api.IRequest; +import at.gv.egovernment.moa.id.data.IAuthData; + + +public interface IStatisticLogger { + + public void logSuccessOperation(IRequest protocolRequest, IAuthData authData, boolean isSSOSession); + + public void logErrorOperation(Throwable throwable); + + public void logErrorOperation(Throwable throwable, IRequest errorRequest); + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/StatisticLogger.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/StatisticLogger.java index 0171f9d90..34bdd350b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/StatisticLogger.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/advancedlogging/StatisticLogger.java @@ -33,6 +33,7 @@ import javax.xml.bind.Unmarshaller; import org.apache.commons.lang3.StringEscapeUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate; @@ -48,6 +49,7 @@ 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.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; +import at.gv.egovernment.moa.id.commons.config.SpringProfileConstants; import at.gv.egovernment.moa.id.commons.db.StatisticLogDBUtils; import at.gv.egovernment.moa.id.commons.db.dao.statistic.StatisticLog; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; @@ -60,7 +62,7 @@ import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; @Service("StatisticLogger") -public class StatisticLogger { +public class StatisticLogger implements IStatisticLogger{ private static final String GENERIC_LOCALBKU = ":3496/https-security-layer-request"; private static final String GENERIC_HANDYBKU = "https://www.handy-signatur.at/"; @@ -79,6 +81,7 @@ public class StatisticLogger { @Autowired AuthConfiguration authConfig; @Autowired IAuthenticationSessionStoreage authenticatedSessionStorage; + @Autowired StatisticLogDBUtils statisticLogDBUtils; public void logSuccessOperation(IRequest protocolRequest, IAuthData authData, boolean isSSOSession) { @@ -191,7 +194,7 @@ public class StatisticLogger { try { - StatisticLogDBUtils.saveOrUpdate(dblog); + statisticLogDBUtils.saveOrUpdate(dblog); } catch (MOADatabaseException e) { Logger.warn("Statistic Log can not be stored into Database", e); @@ -217,7 +220,7 @@ public class StatisticLogger { try { - StatisticLogDBUtils.saveOrUpdate(dblog); + statisticLogDBUtils.saveOrUpdate(dblog); } catch (MOADatabaseException e) { Logger.warn("Statistic Log can not be stored into Database", e); @@ -268,7 +271,7 @@ public class StatisticLogger { try { - StatisticLogDBUtils.saveOrUpdate(dblog); + statisticLogDBUtils.saveOrUpdate(dblog); } catch (MOADatabaseException e) { Logger.warn("Statistic Log can not be stored into Database", e); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationSessionCleaner.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationSessionCleaner.java index e0552c337..bbb322a4f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationSessionCleaner.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationSessionCleaner.java @@ -8,6 +8,8 @@ import java.util.List; import org.hibernate.HibernateException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import at.gv.egovernment.moa.id.advancedlogging.TransactionIDUtils; @@ -29,6 +31,7 @@ import at.gv.egovernment.moa.util.MiscUtil; * @version $Id$ */ @Service("AuthenticationSessionCleaner") +@EnableScheduling public class AuthenticationSessionCleaner implements Runnable { @Autowired private IAuthenticationSessionStoreage authenticationSessionStorage; @@ -36,7 +39,7 @@ public class AuthenticationSessionCleaner implements Runnable { @Autowired protected AuthConfiguration authConfig; /** interval the <code>AuthenticationSessionCleaner</code> is run in */ - private static final long SESSION_CLEANUP_INTERVAL = 5 * 60; // 5 min + private static final long SESSION_CLEANUP_INTERVAL = 5 * 60 *1000 ; // 5 min /** * Runs the thread. Cleans the <code>AuthenticationServer</code> session store @@ -45,8 +48,8 @@ public class AuthenticationSessionCleaner implements Runnable { * Cleans up expired session and authentication data stores. * */ + @Scheduled(fixedRate = SESSION_CLEANUP_INTERVAL) public void run() { - while (true) { try { Logger.debug("AuthenticationSessionCleaner run"); Date now = new Date(); @@ -66,7 +69,7 @@ public class AuthenticationSessionCleaner implements Runnable { try { try { Object entry = transactionStorage.get(entryKey); - //if entry is an exception --> log it because is could be unhandled + //if entry is an exception --> log it because it could be unhandled if (entry != null && entry instanceof ExceptionContainer) { ExceptionContainer exContainer = (ExceptionContainer) entry; @@ -115,12 +118,6 @@ public class AuthenticationSessionCleaner implements Runnable { } catch (Exception e) { Logger.error(MOAIDMessageProvider.getInstance().getMessage("cleaner.01", null), e); } - try { - Thread.sleep(SESSION_CLEANUP_INTERVAL * 1000); - } - catch (InterruptedException e) { - } - } } /** @@ -143,18 +140,4 @@ public class AuthenticationSessionCleaner implements Runnable { } } } - - /** - * start the sessionCleaner - */ - public static void start(Runnable clazz) { - // start the session cleanup thread - Thread sessionCleaner = - new Thread(clazz, "AuthenticationSessionCleaner"); - sessionCleaner.setName("SessionCleaner"); - sessionCleaner.setDaemon(true); - sessionCleaner.setPriority(Thread.MIN_PRIORITY); - sessionCleaner.start(); - } - } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDAsExtensionProcessor.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/IDestroyableObject.java index 5837d7dbf..6f98357e2 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDAsExtensionProcessor.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/IDestroyableObject.java @@ -20,29 +20,17 @@ * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. */ -package at.gv.egovernment.moa.id.auth.modules.eidas.engine; - -import java.util.HashSet; -import java.util.Set; - -import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; -import eu.eidas.auth.engine.core.ExtensionProcessorI; -import eu.eidas.auth.engine.core.eidas.EidasExtensionProcessor; +package at.gv.egovernment.moa.id.auth; /** * @author tlenz * */ -public class MOAeIDAsExtensionProcessor extends EidasExtensionProcessor implements ExtensionProcessorI { - +public interface IDestroyableObject { /** - * Add only eIDAS attributes which are supported by Austrian eIDAS node + * Manually deep destroy a Java object with all child objects like timers and threads * */ - @Override - public Set<String> getSupportedAttributes(){ - Set<String> supportedAttributes=new HashSet<String>( Constants.METADATA_POSSIBLE_ATTRIBUTES.keySet()); - - return supportedAttributes; - } + public void fullyDestroy(); + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/IGarbageCollectorProcessing.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/IGarbageCollectorProcessing.java index a1008e883..27d142f2c 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/IGarbageCollectorProcessing.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/IGarbageCollectorProcessing.java @@ -20,7 +20,7 @@ * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. */ -package at.gv.egovernment.moa.id.config.auth; +package at.gv.egovernment.moa.id.auth; /** * @author tlenz diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAGarbageCollector.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAGarbageCollector.java new file mode 100644 index 000000000..52e30a2f0 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAGarbageCollector.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + *******************************************************************************/ +package at.gv.egovernment.moa.id.auth; + + +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import at.gv.egovernment.moa.logging.Logger; + +@Service("MOAGarbageCollector") +@EnableScheduling +public class MOAGarbageCollector implements Runnable { + + @Autowired ApplicationContext context; + + private static final long INTERVAL = 24 * 60 * 60 * 1000; // 24 hours + //private static final long INITAL_DELAY = 12 * 60 * 60 * 1000; // 12 hours + + private static final long INITAL_DELAY = 2 * 60 * 1000; // 12 hours + +// private static final List<IGarbageCollectorProcessing> processModules = +// new ArrayList<IGarbageCollectorProcessing>(); + + + @Scheduled(fixedRate = INTERVAL, initialDelay = INITAL_DELAY) + public void run() { + + Map<String, IGarbageCollectorProcessing> processModules = + context.getBeansOfType(IGarbageCollectorProcessing.class); + + if (processModules != null) { + Iterator<Entry<String, IGarbageCollectorProcessing>> interator = processModules.entrySet().iterator(); + while (interator.hasNext()) { + try { + interator.next().getValue().runGarbageCollector(); + + } catch (Throwable e1) { + Logger.warn("Garbage collection FAILED in some module.", e1); + + } + + } + } + } + +// /** +// * Add a module to MOA internal garbage collector. Every module is executed once a day +// * +// * @param modul Module which should be executed by the garbage collector. +// */ +// public static void addModulForGarbageCollection(IGarbageCollectorProcessing modul) { +// processModules.add(modul); +// +// } + +// public static void start() { +// // start the session cleanup thread +// Thread configLoader = new Thread(new MOAGarbageCollector(), "MOAGarbageCollector"); +// configLoader.setName("MOAGarbageCollectorr"); +// configLoader.setDaemon(true); +// configLoader.setPriority(Thread.MIN_PRIORITY); +// configLoader.start(); +// } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java index d1cf3338a..11f47052e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthInitializer.java @@ -36,18 +36,16 @@ import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.utils.MOAIDMessageProvider; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; -import at.gv.egovernment.moa.id.config.auth.MOAGarbageCollector; import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.id.util.SSLUtils; import at.gv.egovernment.moa.logging.Logger; -import at.gv.egovernment.moa.logging.LoggingContext; -import at.gv.egovernment.moa.logging.LoggingContextManager; import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; import at.gv.egovernment.moa.spss.server.iaik.config.IaikConfigurator; -import at.gv.egovernment.moa.util.Constants; import at.gv.egovernment.moa.util.MiscUtil; +import at.gv.egovernment.moaspss.logging.LoggingContext; +import at.gv.egovernment.moaspss.logging.LoggingContextManager; import iaik.pki.PKIException; -import iaik.security.ecc.provider.ECCProvider; +import iaik.security.ec.provider.ECCelerate; import iaik.security.provider.IAIK; /** @@ -104,17 +102,11 @@ public class MOAIDAuthInitializer { Logger.info("Loading Java security providers."); IAIK.addAsProvider(); - ECCProvider.addAsProvider(); + ECCelerate.addAsProvider(); // Initializes SSLSocketFactory store SSLUtils.initialize(); - // Initializes Namespace Map - Constants.nSMap.put(Constants.SAML_PREFIX, Constants.SAML_NS_URI); - Constants.nSMap.put(Constants.ECDSA_PREFIX, - "http://www.w3.org/2001/04/xmldsig-more#"); - Constants.nSMap.put(Constants.DSIG_PREFIX, Constants.DSIG_NS_URI); - //seed the random number generator Random.seedRandom(); Logger.debug("Random-number generator is seeded."); @@ -147,7 +139,12 @@ public class MOAIDAuthInitializer { //ECCProvider.addAsProvider(); Security.insertProviderAt(IAIK.getInstance(), 0); - Security.addProvider(new ECCProvider()); + + ECCelerate eccProvider = ECCelerate.getInstance(); + if (Security.getProvider(eccProvider.getName()) != null) + Security.removeProvider(eccProvider.getName()); + + Security.addProvider(new ECCelerate()); if (Logger.isDebugEnabled()) { Logger.debug("Loaded Security Provider:"); @@ -156,12 +153,5 @@ public class MOAIDAuthInitializer { Logger.debug(i + ": " + providerList[i].getName() + " Version " + providerList[i].getVersion()); } - - - // Starts the session cleaner thread to remove unpicked authentication data - AuthenticationSessionCleaner sessioncleaner = rootContext.getBean("AuthenticationSessionCleaner", AuthenticationSessionCleaner.class); - AuthenticationSessionCleaner.start(sessioncleaner); - - MOAGarbageCollector.start(); } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java index 908c7e7b6..16d320ea5 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java @@ -106,6 +106,7 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants { @Autowired protected AuthConfiguration authConfig; @Autowired private AttributQueryBuilder attributQueryBuilder; @Autowired private SAMLVerificationEngineSP samlVerificationEngine; + @Autowired(required=true) private MOAMetadataProvider metadataProvider; public IAuthData buildAuthenticationData(IRequest pendingReq, @@ -222,7 +223,7 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants { try { samlVerificationEngine.verifyIDPResponse(intfResp, TrustEngineFactory.getSignatureKnownKeysTrustEngine( - MOAMetadataProvider.getInstance())); + metadataProvider)); //create assertion attribute extractor from AttributeQuery response return new AssertionAttributeExtractor(intfResp); @@ -1106,10 +1107,15 @@ public class AuthenticationDataBuilder extends MOAIDAuthConstants { String eIDASOutboundCountry = pendingReq.getGenericData(RequestImpl.eIDAS_GENERIC_REQ_DATA_COUNTRY, String.class); + //TODO: maybe find a better solution + String cititzenCountryCode = + authConfig.getBasicMOAIDConfiguration("moa.id.protocols.eIDAS.node.countrycode", + MOAIDAuthConstants.COUNTRYCODE_AUSTRIA); + if (Constants.URN_PREFIX_BASEID.equals(baseIDType)) { - if (MiscUtil.isNotEmpty(eIDASOutboundCountry) && !COUNTRYCODE_AUSTRIA.equals(eIDASOutboundCountry)) { + if (MiscUtil.isNotEmpty(eIDASOutboundCountry) && !cititzenCountryCode.equals(eIDASOutboundCountry)) { Pair<String, String> eIDASID = new BPKBuilder().buildeIDASIdentifer(baseIDType, baseID, - COUNTRYCODE_AUSTRIA, eIDASOutboundCountry); + cititzenCountryCode, eIDASOutboundCountry); Logger.debug("Authenticate user with bPK:" + eIDASID.getFirst() + " Type:" + eIDASID.getSecond()); return eIDASID; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/MISSimpleClientException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/MISSimpleClientException.java index 718c35df3..ab3d2cae2 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/MISSimpleClientException.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/exception/MISSimpleClientException.java @@ -73,6 +73,10 @@ public class MISSimpleClientException extends MOAIDException { super(message, null, cause);
}
+ public MISSimpleClientException(String message, Object[] params, Throwable cause) {
+ super(message, params, cause);
+ }
+
/**
* @return the bkuErrorCode
*/
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java index e3efdeac0..1431911a3 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AbstractController.java @@ -33,10 +33,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.ExceptionHandler; import com.google.common.net.MediaType; - +import at.gv.egovernment.moa.id.advancedlogging.IStatisticLogger; import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; -import at.gv.egovernment.moa.id.advancedlogging.StatisticLogger; import at.gv.egovernment.moa.id.auth.exception.InvalidProtocolRequestException; import at.gv.egovernment.moa.id.auth.exception.ProtocolNotActiveException; import at.gv.egovernment.moa.id.auth.frontend.builder.DefaultGUIFormBuilderConfiguration; @@ -71,7 +70,7 @@ public abstract class AbstractController extends MOAIDAuthConstants { public static final String ERROR_CODE_PARAM = "errorid"; - @Autowired protected StatisticLogger statisticLogger; + @Autowired protected IStatisticLogger statisticLogger; @Autowired protected IRequestStorage requestStorage; @Autowired protected ITransactionStorage transactionStorage; @Autowired protected MOAReversionLogger revisionsLogger; @@ -141,12 +140,12 @@ public abstract class AbstractController extends MOAIDAuthConstants { revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.TRANSACTION_ERROR); transactionStorage.put(key, new ExceptionContainer(pendingReq.getUniqueSessionIdentifier(), - pendingReq.getUniqueTransactionIdentifier(), loggedException)); + pendingReq.getUniqueTransactionIdentifier(), loggedException),-1); } else { transactionStorage.put(key, new ExceptionContainer(null, - null, loggedException)); + null, loggedException),-1); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java index 66e8757ad..5e09380ae 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java @@ -179,7 +179,7 @@ public class IDPSingleLogOutServlet extends AbstractController { else statusCode = MOAIDAuthConstants.SLOSTATUS_ERROR; - transactionStorage.put(artifact, statusCode); + transactionStorage.put(artifact, statusCode, -1); redirectURL = HTTPUtils.addURLParameter(redirectURL, MOAIDAuthConstants.PARAM_SLOSTATUS, artifact); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationProviderImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationProviderImpl.java index 5c2f86732..67ad4762c 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationProviderImpl.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationProviderImpl.java @@ -46,6 +46,7 @@ package at.gv.egovernment.moa.id.config; +import java.util.ArrayList; import java.util.Map; import java.util.Properties; @@ -53,6 +54,7 @@ import org.hibernate.cfg.Configuration; import at.gv.egovernment.moa.id.commons.api.ConfigurationProvider; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; +import at.gv.egovernment.moa.id.commons.config.SpringProfileConstants; import at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils; import at.gv.egovernment.moa.id.commons.db.StatisticLogDBUtils; import at.gv.egovernment.moa.id.commons.db.dao.session.AssertionStore; @@ -185,6 +187,10 @@ public abstract class ConfigurationProviderImpl implements ConfigurationProvider String propertyName = key.toString().substring(propPrefix.length()); moaSessionProp.put(propertyName, props.get(key.toString())); } + if (key.toString().startsWith(propPrefix+"dbcp")) { + String propertyName = "hibernate."+(key.toString().substring(propPrefix.length())); + moaSessionProp.put(propertyName, props.get(key.toString())); + } } // read Config Hibernate properties @@ -222,17 +228,17 @@ public abstract class ConfigurationProviderImpl implements ConfigurationProvider config.addAnnotatedClass(InterfederationSessionStore.class); //config.addAnnotatedClass(ProcessInstanceStore.class); config.addProperties(moaSessionProp); - MOASessionDBUtils.initHibernate(config, moaSessionProp); + //MOASessionDBUtils.initHibernate(config, moaSessionProp); //initial advanced logging - if (Boolean.valueOf(props.getProperty("configuration.advancedlogging.active", "false"))) { - Logger.info("Advanced statistic log is activated, starting initialization process ..."); - Configuration statisticconfig = new Configuration(); - statisticconfig.addAnnotatedClass(StatisticLog.class); - statisticconfig.addProperties(statisticProps); - StatisticLogDBUtils.initHibernate(statisticconfig, statisticProps); - Logger.info("Advanced statistic log is initialized."); - } +// if (Boolean.valueOf(props.getProperty("configuration.advancedlogging.active", "false"))) { +// Logger.info("Advanced statistic log is activated, starting initialization process ..."); +// Configuration statisticconfig = new Configuration(); +// statisticconfig.addAnnotatedClass(StatisticLog.class); +// statisticconfig.addProperties(statisticProps); +// StatisticLogDBUtils.initHibernate(statisticconfig, statisticProps); +// Logger.info("Advanced statistic log is initialized."); +// } } Logger.trace("Hibernate initialization finished."); @@ -267,6 +273,7 @@ public abstract class ConfigurationProviderImpl implements ConfigurationProvider eGovUtilsConfig = new EgovUtilPropertiesConfiguration(eGovUtilsConfigProp, rootConfigFileDir); } + this.generateActiveProfiles(props); } @@ -277,5 +284,24 @@ public abstract class ConfigurationProviderImpl implements ConfigurationProvider public EgovUtilPropertiesConfiguration geteGovUtilsConfig() { return eGovUtilsConfig; } + + private ArrayList<String> activeProfiles = new ArrayList<String>(); + + public void generateActiveProfiles(Properties props){ + if (Boolean.valueOf(props.getProperty("configuration.advancedlogging.active", "false"))) { + activeProfiles.add(SpringProfileConstants.ADVANCED_LOG); + }else{ + activeProfiles.add("advancedLogOff"); + } + if (Boolean.valueOf(props.getProperty("redis.active", "false"))) { + activeProfiles.add(SpringProfileConstants.REDIS_BACKEND); + }else{ + activeProfiles.add(SpringProfileConstants.DB_BACKEND); + } + } + + public String[] getActiveProfiles(){ + return activeProfiles.toArray(new String[0]); + } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/MOAGarbageCollector.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/MOAGarbageCollector.java deleted file mode 100644 index 1072bec5c..000000000 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/MOAGarbageCollector.java +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -package at.gv.egovernment.moa.id.config.auth; - - -import java.util.ArrayList; -import java.util.List; - -import at.gv.egovernment.moa.logging.Logger; - -public class MOAGarbageCollector implements Runnable { - - private static final long INTERVAL = 24 * 60 * 60; // 24 hours - private static final List<IGarbageCollectorProcessing> processModules = - new ArrayList<IGarbageCollectorProcessing>(); - - public void run() { - while (true) { - try { - Thread.sleep(INTERVAL * 1000); - - try { - for (IGarbageCollectorProcessing element : processModules) - element.runGarbageCollector(); - - } catch (Throwable e1) { - Logger.warn("Garbage collection FAILED in some module.", e1); - } - - } catch (Throwable e) { - Logger.warn("MOA-ID garbage collection is not possible, actually.", e); - - } finally { - - } - } - } - - /** - * Add a module to MOA internal garbage collector. Every module is executed once a day - * - * @param modul Module which should be executed by the garbage collector. - */ - public static void addModulForGarbageCollection(IGarbageCollectorProcessing modul) { - processModules.add(modul); - - } - - public static void start() { - // start the session cleanup thread - Thread configLoader = new Thread(new MOAGarbageCollector(), "MOAGarbageCollector"); - configLoader.setName("MOAGarbageCollectorr"); - configLoader.setDaemon(true); - configLoader.setPriority(Thread.MIN_PRIORITY); - configLoader.start(); - } -} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java index b1bba6c17..6a6359058 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java @@ -122,7 +122,10 @@ public String getIdentityLinkDomainIdentifier() { if (MiscUtil.isNotEmpty(type) && MiscUtil.isNotEmpty(value)) { if (MOAIDConstants.IDENIFICATIONTYPE_STORK.equals(type)) { return MOAIDConstants.PREFIX_STORK + "AT" + "+" + value; - + + } else if (MOAIDConstants.IDENIFICATIONTYPE_EIDAS.equals(type)) { + return MOAIDConstants.PREFIX_EIDAS + value; + } else { return MOAIDConstants.PREFIX_WPBK + type + "+" + value; @@ -395,25 +398,13 @@ public boolean isOnlyMandateAllowed() { * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getQaaLevel() */ @Override -public Integer getQaaLevel() { - try { - Integer storkQAALevel = Integer.parseInt(oaConfiguration.get(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_MINQAALEVEL)); - - if (storkQAALevel >= 1 && - storkQAALevel <= 4) - return storkQAALevel; - - else { - Logger.info("STORK minimal QAA level is not in a valid range. Use minimal QAA 4"); - return 4; +public String getQaaLevel() { + String eidasLoALevel = oaConfiguration.get(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_MINQAALEVEL); + if (MiscUtil.isEmpty(eidasLoALevel)) + return MOAIDConstants.eIDAS_LOA_HIGH; + else + return eidasLoALevel; - } - - } catch (NumberFormatException e) { - Logger.warn("STORK minimal QAA level is not a number.", e); - return 4; - - } } /* (non-Javadoc) diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java index 348b1c45a..e62a4a8d5 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/PropertyBasedAuthConfigurationProvider.java @@ -228,6 +228,12 @@ public class PropertyBasedAuthConfigurationProvider extends ConfigurationProvide } + public String getBasicMOAIDConfiguration(final String key, final String defaultValue) { + return properties.getProperty(key, defaultValue); + + } + + /* (non-Javadoc) * @see at.gv.egovernment.moa.id.config.auth.AuthConfiguration#getPropertyWithKey(java.lang.String) */ diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/data/DynamicOAAuthParameters.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/data/DynamicOAAuthParameters.java index 8d70b1444..9fd58b5c7 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/data/DynamicOAAuthParameters.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/data/DynamicOAAuthParameters.java @@ -201,7 +201,7 @@ public class DynamicOAAuthParameters implements IOAAuthParameters, Serializable{ * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getQaaLevel() */ @Override - public Integer getQaaLevel() { + public String getQaaLevel() { // TODO Auto-generated method stub return null; } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java index a1f2c6558..34b250bf0 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java @@ -104,7 +104,8 @@ public class AuthenticationManager extends MOAIDAuthConstants { @Autowired private SingleLogOutBuilder sloBuilder; @Autowired private SAMLVerificationEngineSP samlVerificationEngine; @Autowired private IGUIFormBuilder guiBuilder; - + @Autowired(required=true) private MOAMetadataProvider metadataProvider; + public void performSingleLogOut(HttpServletRequest httpReq, HttpServletResponse httpResp, AuthenticationSession session, PVPTargetConfiguration pvpReq) throws MOAIDException { performSingleLogOut(httpReq, httpResp, session, pvpReq, null); @@ -527,7 +528,7 @@ public class AuthenticationManager extends MOAIDAuthConstants { } else { samlVerificationEngine.verifySLOResponse(sloResp, - TrustEngineFactory.getSignatureKnownKeysTrustEngine(MOAMetadataProvider.getInstance())); + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); } @@ -569,7 +570,7 @@ public class AuthenticationManager extends MOAIDAuthConstants { } //put SLO process-information into transaction storage - transactionStorage.put(relayState, sloContainer); + transactionStorage.put(relayState, sloContainer, -1); if (MiscUtil.isEmpty(authURL)) authURL = pvpReq.getAuthURL(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java index 85e4dc99b..ffc6012c9 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestImpl.java @@ -32,6 +32,8 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; +import org.opensaml.saml2.metadata.provider.MetadataProvider; + import at.gv.egovernment.moa.id.advancedlogging.TransactionIDUtils; import at.gv.egovernment.moa.id.commons.MOAIDConstants; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; @@ -52,7 +54,12 @@ public abstract class RequestImpl implements IRequest, Serializable{ public static final String DATAID_REQUESTED_ATTRIBUTES = "requestedAttributes"; public static final String DATAID_INTERFEDERATIOIDP_ENTITYID = "interIDPEntityID"; + public static final String DATAID_REQUESTER_IP_ADDRESS = "requesterIP"; + public static final String eIDAS_GENERIC_REQ_DATA_COUNTRY = "country"; + public static final String eIDAS_GENERIC_REQ_DATA_LEVELOFASSURENCE = "eIDAS_LoA"; + + private static final long serialVersionUID = 1L; @@ -91,10 +98,10 @@ public abstract class RequestImpl implements IRequest, Serializable{ */ public final void initialize(HttpServletRequest req) throws ConfigurationException { //set requestID - requestID = Random.nextRandom(); + requestID = Random.nextLongRandom(); //set unique transaction identifier for logging - uniqueTransactionIdentifer = Random.nextRandom(); + uniqueTransactionIdentifer = Random.nextLongRandom(); TransactionIDUtils.setTransactionId(uniqueTransactionIdentifer); @@ -167,6 +174,15 @@ public abstract class RequestImpl implements IRequest, Serializable{ else Logger.warn("No unique session-identifier FOUND, but it should be allready set into request!?!"); + //set requester's IP address + try { + setGenericDataToSession(DATAID_REQUESTER_IP_ADDRESS, req.getRemoteAddr()); + + } catch (SessionDataStorageException e) { + Logger.warn("Can not store remote IP address to 'pendingRequest' during an exception." , e); + + } + } /** @@ -174,7 +190,7 @@ public abstract class RequestImpl implements IRequest, Serializable{ * * @return List of PVP 2.1 attribute names with maps all protocol specific attributes */ - public abstract Collection<String> getRequestedAttributes(); + public abstract Collection<String> getRequestedAttributes(MetadataProvider metadataProvider); public void setOAURL(String value) { oaURL = value; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestStorage.java index 1b550881e..eec48e0f3 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestStorage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/RequestStorage.java @@ -68,7 +68,7 @@ public class RequestStorage implements IRequestStorage{ public void storePendingRequest(IRequest pendingRequest) throws MOAIDException { try { if (pendingRequest instanceof IRequest) { - transactionStorage.put(((IRequest)pendingRequest).getRequestID(), pendingRequest); + transactionStorage.put(((IRequest)pendingRequest).getRequestID(), pendingRequest, -1); } else { throw new MOAIDException("auth.20", null); @@ -123,6 +123,7 @@ public class RequestStorage implements IRequestStorage{ ((RequestImpl)pendingRequest).setRequestID(newRequestID); transactionStorage.changeKey(oldRequestID, newRequestID, pendingRequest); + //only delete oldRequestID, no change. return newRequestID; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java index bc7dd272b..0799760ce 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/SSOManager.java @@ -63,6 +63,7 @@ public class SSOManager { @Autowired private IAuthenticationSessionStoreage authenticatedSessionStore; @Autowired protected AuthConfiguration authConfig; + @Autowired private MOASessionDBUtils moaSessionDBUtils; /** * Check if interfederation IDP is requested via HTTP GET parameter or if interfederation cookie exists. @@ -159,7 +160,7 @@ public class SSOManager { } else { Logger.warn("MOASession is marked as interfederated SSO session but no interfederated IDP is found. Switch to local authentication ..."); - MOASessionDBUtils.delete(storedSession); + moaSessionDBUtils.delete(storedSession); } } @@ -200,7 +201,7 @@ public class SSOManager { public String existsOldSSOSession(String ssoId) { Logger.trace("Check that the SSOID has already been used"); - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); List<OldSSOSessionIDStore> result; @@ -289,7 +290,7 @@ public class SSOManager { //no local SSO session exist -> request interfederated IDP Logger.info("Delete interfederated IDP " + selectedIDP.getIdpurlprefix() + " from MOASession " + storedSession.getSessionid()); - MOASessionDBUtils.delete(selectedIDP); + moaSessionDBUtils.delete(selectedIDP); } else { Logger.warn("MOASession is marked as interfederated SSO session but no interfederated IDP is found. Switch to local authentication ..."); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/dao/ProcessInstanceStoreDAOImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/dao/ProcessInstanceStoreDAOImpl.java index a9a9322ad..428931b5e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/dao/ProcessInstanceStoreDAOImpl.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/dao/ProcessInstanceStoreDAOImpl.java @@ -22,7 +22,7 @@ public class ProcessInstanceStoreDAOImpl implements ProcessInstanceStoreDAO { @Override public void saveOrUpdate(ProcessInstanceStore pIStore) throws MOADatabaseException { try { - transactionStorage.put(pIStore.getProcessInstanceId(), pIStore); + transactionStorage.put(pIStore.getProcessInstanceId(), pIStore, -1); // MOASessionDBUtils.saveOrUpdate(pIStore); log.debug("Store process instance with='{}' in the database.", pIStore.getProcessInstanceId()); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java index 2168316ab..6375f26a3 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java @@ -80,6 +80,8 @@ public class AttributQueryAction implements IAction { @Autowired private AuthenticationDataBuilder authDataBuilder; @Autowired private IDPCredentialProvider pvpCredentials; @Autowired private AuthConfiguration authConfig; + @Autowired private MOASessionDBUtils moaSessionDBUtils; + @Autowired(required=true) private MOAMetadataProvider metadataProvider; private final static List<String> DEFAULTSTORKATTRIBUTES = Arrays.asList( new String[]{PVPConstants.EID_STORK_TOKEN_NAME}); @@ -139,7 +141,7 @@ public class AttributQueryAction implements IAction { //build PVP 2.1 response Response authResponse = AuthResponseBuilder.buildResponse( - MOAMetadataProvider.getInstance(), issuerEntityID, attrQuery, date, + metadataProvider, issuerEntityID, attrQuery, date, assertion, authConfig.isPVP2AssertionEncryptionActive()); SoapBinding decoder = new SoapBinding(); @@ -198,7 +200,7 @@ public class AttributQueryAction implements IAction { ((PVPTargetConfiguration) pendingReq).getRequest().getInboundMessage() instanceof AttributeQuery) { try { activeOA.setAttributeQueryUsed(true); - MOASessionDBUtils.saveOrUpdate(activeOA); + moaSessionDBUtils.saveOrUpdate(activeOA); } catch (MOADatabaseException e) { Logger.error("MOASession interfederation information can not stored to database.", e); @@ -251,11 +253,11 @@ public class AttributQueryAction implements IAction { //mark attribute request as used if (nextIDPInformation.isStoreSSOInformation()) { nextIDPInformation.setAttributesRequested(true); - MOASessionDBUtils.saveOrUpdate(nextIDPInformation); + moaSessionDBUtils.saveOrUpdate(nextIDPInformation); //delete federated IDP from Session } else { - MOASessionDBUtils.delete(nextIDPInformation); + moaSessionDBUtils.delete(nextIDPInformation); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java index 8de44a2e8..aac49844e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java @@ -61,6 +61,7 @@ import at.gv.egovernment.moa.logging.Logger; public class AuthenticationAction implements IAction { @Autowired IDPCredentialProvider pvpCredentials; @Autowired AuthConfiguration authConfig; + @Autowired(required=true) private MOAMetadataProvider metadataProvider; public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException { @@ -70,7 +71,7 @@ public class AuthenticationAction implements IAction { //get basic information MOARequest moaRequest = (MOARequest) pvpRequest.getRequest(); AuthnRequest authnRequest = (AuthnRequest) moaRequest.getSamlRequest(); - EntityDescriptor peerEntity = moaRequest.getEntityMetadata(); + EntityDescriptor peerEntity = moaRequest.getEntityMetadata(metadataProvider); AssertionConsumerService consumerService = SAML2Utils.createSAMLObject(AssertionConsumerService.class); @@ -94,7 +95,7 @@ public class AuthenticationAction implements IAction { peerEntity, date, consumerService, sloInformation); Response authResponse = AuthResponseBuilder.buildResponse( - MOAMetadataProvider.getInstance(), issuerEntityID, authnRequest, + metadataProvider, issuerEntityID, authnRequest, date, assertion, authConfig.isPVP2AssertionEncryptionActive()); IEncoder binding = null; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java index 350690f82..f09a3c30c 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java @@ -104,6 +104,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { @Autowired IDPCredentialProvider pvpCredentials; @Autowired SAMLVerificationEngineSP samlVerificationEngine; + @Autowired(required=true) private MOAMetadataProvider metadataProvider; public static final String NAME = PVP2XProtocol.class.getName(); public static final String PATH = "id_pvp2x"; @@ -187,7 +188,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { //get POST-Binding decoder implementation InboundMessage msg = (InboundMessage) new PostBinding().decode( - req, resp, MOAMetadataProvider.getInstance(), false, + req, resp, metadataProvider, false, new MOAURICompare(PVPConfiguration.getInstance().getIDPSSOPostService(pendingReq.getAuthURL()))); pendingReq.setRequest(msg); @@ -240,7 +241,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { //get POST-Binding decoder implementation InboundMessage msg = (InboundMessage) new RedirectBinding().decode( - req, resp, MOAMetadataProvider.getInstance(), false, + req, resp, metadataProvider, false, new MOAURICompare(PVPConfiguration.getInstance().getIDPSSORedirectService(pendingReq.getAuthURL()))); pendingReq.setRequest(msg); @@ -294,7 +295,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { //get POST-Binding decoder implementation InboundMessage msg = (InboundMessage) new SoapBinding().decode( - req, resp, MOAMetadataProvider.getInstance(), false, + req, resp, metadataProvider, false, new MOAURICompare(PVPConfiguration.getInstance().getIDPSSOPostService(pendingReq.getAuthURL()))); pendingReq.setRequest(msg); @@ -336,7 +337,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { if(!msg.isVerified()) { samlVerificationEngine.verify(msg, - TrustEngineFactory.getSignatureKnownKeysTrustEngine(MOAMetadataProvider.getInstance())); + TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); msg.setVerified(true); } @@ -494,7 +495,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { msg = (MOARequest) inMsg; - EntityDescriptor metadata = msg.getEntityMetadata(); + EntityDescriptor metadata = msg.getEntityMetadata(metadataProvider); if(metadata == null) { throw new NoMetadataInformationException(); } @@ -526,7 +527,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { boolean isAllowedDestination = false; for (String prefix : allowedPublicURLPrefix) { - if (!resp.getDestination().startsWith( + if (resp.getDestination().startsWith( prefix)) { isAllowedDestination = true; break; @@ -644,7 +645,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { throw new MOAIDException("Unsupported request", new Object[] {}); } - EntityDescriptor metadata = moaRequest.getEntityMetadata(); + EntityDescriptor metadata = moaRequest.getEntityMetadata(metadataProvider); if(metadata == null) { throw new NoMetadataInformationException(); } @@ -736,7 +737,7 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController { } } - String oaURL = moaRequest.getEntityMetadata().getEntityID(); + String oaURL = moaRequest.getEntityMetadata(metadataProvider).getEntityID(); oaURL = StringEscapeUtils.escapeHtml(oaURL); IOAAuthParameters oa = authConfig.getOnlineApplicationParameter(oaURL); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPAssertionStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPAssertionStorage.java index 0dd309154..62105abda 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPAssertionStorage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPAssertionStorage.java @@ -49,7 +49,7 @@ public class PVPAssertionStorage implements SAMLArtifactMap { samlMessage); try { - transactionStorage.put(artifact, assertion); + transactionStorage.put(artifact, assertion, -1); } catch (MOADatabaseException e) { // TODO Insert Error Handling, if Assertion could not be stored diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java index e7f2a7d4b..caf66942e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java @@ -32,6 +32,7 @@ import org.opensaml.saml2.core.impl.AuthnRequestImpl; import org.opensaml.saml2.metadata.AttributeConsumingService; import org.opensaml.saml2.metadata.RequestedAttribute; import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -54,7 +55,6 @@ public class PVPTargetConfiguration extends RequestImpl { private static final long serialVersionUID = 4889919265919638188L; - InboundMessage request; String binding; String consumerURL; @@ -88,14 +88,14 @@ public class PVPTargetConfiguration extends RequestImpl { * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes() */ @Override - public Collection<String> getRequestedAttributes() { + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider) { Map<String, String> reqAttr = new HashMap<String, String>(); for (String el : PVP2XProtocol.DEFAULTREQUESTEDATTRFORINTERFEDERATION) reqAttr.put(el, ""); try { - SPSSODescriptor spSSODescriptor = getRequest().getEntityMetadata().getSPSSODescriptor(SAMLConstants.SAML20P_NS); + SPSSODescriptor spSSODescriptor = getRequest().getEntityMetadata(metadataProvider).getSPSSODescriptor(SAMLConstants.SAML20P_NS); if (spSSODescriptor.getAttributeConsumingServices() != null && spSSODescriptor.getAttributeConsumingServices().size() > 0) { @@ -139,5 +139,6 @@ public class PVPTargetConfiguration extends RequestImpl { } - } + } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SingleLogOutAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SingleLogOutAction.java index 52bf16247..c762e2505 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SingleLogOutAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SingleLogOutAction.java @@ -24,17 +24,11 @@ package at.gv.egovernment.moa.id.protocols.pvp2x; import java.io.Serializable; import java.io.UnsupportedEncodingException; -import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.SerializationUtils; -import org.hibernate.HibernateException; -import org.hibernate.Query; -import org.hibernate.Session; -import org.hibernate.Transaction; -import org.hibernate.resource.transaction.spi.TransactionStatus; import org.opensaml.saml2.core.LogoutRequest; import org.opensaml.saml2.core.LogoutResponse; import org.opensaml.saml2.metadata.SingleLogoutService; @@ -49,7 +43,6 @@ import at.gv.egovernment.moa.id.auth.servlet.RedirectServlet; import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; import at.gv.egovernment.moa.id.commons.api.IRequest; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; -import at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils; import at.gv.egovernment.moa.id.commons.db.dao.session.AssertionStore; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.id.data.IAuthData; @@ -83,8 +76,8 @@ public class SingleLogOutAction implements IAction { @Autowired private ITransactionStorage transactionStorage; @Autowired private SingleLogOutBuilder sloBuilder; @Autowired private MOAReversionLogger revisionsLogger; - - + + /* (non-Javadoc) * @see at.gv.egovernment.moa.id.moduls.IAction#processRequest(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.data.IAuthData) */ @@ -94,142 +87,148 @@ public class SingleLogOutAction implements IAction { IAuthData authData) throws MOAIDException { PVPTargetConfiguration pvpReq = (PVPTargetConfiguration) req; - + if (pvpReq.getRequest() instanceof MOARequest && ((MOARequest)pvpReq.getRequest()).getSamlRequest() instanceof LogoutRequest) { Logger.debug("Process Single LogOut request"); MOARequest samlReq = (MOARequest) pvpReq.getRequest(); LogoutRequest logOutReq = (LogoutRequest) samlReq.getSamlRequest(); - + AuthenticationSession session = authenticationSessionStorage.searchMOASessionWithNameIDandOAID( logOutReq.getIssuer().getValue(), logOutReq.getNameID().getValue()); - - if (session == null) { - Logger.warn("Can not find active SSO session with nameID " - + logOutReq.getNameID().getValue() + " and OA " - + logOutReq.getIssuer().getValue()); - Logger.info("Search active SSO session with SSO session cookie"); - String ssoID = ssomanager.getSSOSessionID(httpReq); - if (MiscUtil.isEmpty(ssoID)) { + + if (session == null) { + Logger.warn("Can not find active SSO session with nameID " + + logOutReq.getNameID().getValue() + " and OA " + + logOutReq.getIssuer().getValue()); + Logger.info("Search active SSO session with SSO session cookie"); + String ssoID = ssomanager.getSSOSessionID(httpReq); + if (MiscUtil.isEmpty(ssoID)) { + Logger.info("Can not find active Session. Single LogOut not possible!"); + SingleLogoutService sloService = sloBuilder.getResponseSLODescriptor(pvpReq); + //LogoutResponse message = sloBuilder.buildSLOErrorResponse(sloService, pvpReq, StatusCode.RESPONDER_URI); + LogoutResponse message = sloBuilder.buildSLOResponseMessage(sloService, pvpReq, null); + Logger.info("Sending SLO success message to requester ..."); + sloBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, samlReq.getRelayState()); + return null; + + } else { + String moasession = ssomanager.getMOASession(ssoID); + try { + session = authenticationSessionStorage.getSession(moasession); + + if (session == null) + throw new MOADatabaseException(); + + } catch (MOADatabaseException e) { Logger.info("Can not find active Session. Single LogOut not possible!"); SingleLogoutService sloService = sloBuilder.getResponseSLODescriptor(pvpReq); //LogoutResponse message = sloBuilder.buildSLOErrorResponse(sloService, pvpReq, StatusCode.RESPONDER_URI); LogoutResponse message = sloBuilder.buildSLOResponseMessage(sloService, pvpReq, null); Logger.info("Sending SLO success message to requester ..."); - sloBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, samlReq.getRelayState()); + sloBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, samlReq.getRelayState()); return null; - - } else { - String moasession = ssomanager.getMOASession(ssoID); - try { - session = authenticationSessionStorage.getSession(moasession); - - if (session == null) - throw new MOADatabaseException(); - - } catch (MOADatabaseException e) { - Logger.info("Can not find active Session. Single LogOut not possible!"); - SingleLogoutService sloService = sloBuilder.getResponseSLODescriptor(pvpReq); - //LogoutResponse message = sloBuilder.buildSLOErrorResponse(sloService, pvpReq, StatusCode.RESPONDER_URI); - LogoutResponse message = sloBuilder.buildSLOResponseMessage(sloService, pvpReq, null); - Logger.info("Sending SLO success message to requester ..."); - sloBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, samlReq.getRelayState()); - return null; - - } - } + + } + } + } + + authManager.performSingleLogOut(httpReq, httpResp, session, pvpReq); + + } else if (pvpReq.getRequest() instanceof MOAResponse && + ((MOAResponse)pvpReq.getRequest()).getResponse() instanceof LogoutResponse) { + Logger.debug("Process Single LogOut response"); + LogoutResponse logOutResp = (LogoutResponse) ((MOAResponse)pvpReq.getRequest()).getResponse(); + + //Transaction tx = null; + + try { + String relayState = pvpReq.getRequest().getRelayState(); + if (MiscUtil.isEmpty(relayState)) { + Logger.warn("SLO Response from " + logOutResp.getIssuer().getValue() + + " has no SAML2 RelayState."); + throw new SLOException("pvp2.19", null); + } - - authManager.performSingleLogOut(httpReq, httpResp, session, pvpReq); - - } else if (pvpReq.getRequest() instanceof MOAResponse && - ((MOAResponse)pvpReq.getRequest()).getResponse() instanceof LogoutResponse) { - Logger.debug("Process Single LogOut response"); - LogoutResponse logOutResp = (LogoutResponse) ((MOAResponse)pvpReq.getRequest()).getResponse(); - - Transaction tx = null; - - try { - String relayState = pvpReq.getRequest().getRelayState(); - if (MiscUtil.isEmpty(relayState)) { - Logger.warn("SLO Response from " + logOutResp.getIssuer().getValue() - + " has no SAML2 RelayState."); - throw new SLOException("pvp2.19", null); - - } - - Session session = MOASessionDBUtils.getCurrentSession(); - boolean storageSuccess = false; - int counter = 0; - - //TODO: add counter to prevent deadlock - + + //Session session = MOASessionDBUtils.getCurrentSession(); + boolean storageSuccess = false; + int counter = 0; + + //TODO: add counter to prevent deadlock + synchronized(this){ while (!storageSuccess) { - tx = session.beginTransaction(); - - List result; - Query query = session.getNamedQuery("getAssertionWithArtifact"); - query.setParameter("artifact", relayState); - result = query.list(); - Logger.trace("Found entries: " + result.size()); - - //Assertion requires an unique artifact - if (result.size() != 1) { + // tx = session.beginTransaction(); + // + // List result; + // Query query = session.getNamedQuery("getAssertionWithArtifact"); + // query.setParameter("artifact", relayState); + // result = query.list(); + // + // + // Logger.trace("Found entries: " + result.size()); + // + // //Assertion requires an unique artifact + // if (result.size() != 1) { + // Logger.trace("No entries found."); + // throw new MOADatabaseException("No sessioninformation found with this ID"); + // } + // + // AssertionStore element = (AssertionStore) result.get(0); + // Object data = SerializationUtils.deserialize(element.getAssertion()); + Logger.debug("Current Thread getAssertionStore: "+Thread.currentThread().getId()); + Object o = transactionStorage.getAssertionStore(relayState); + if(o==null){ Logger.trace("No entries found."); - throw new MOADatabaseException("No sessioninformation found with this ID"); + throw new MOADatabaseException("No sessioninformation found with this ID"); } - - AssertionStore element = (AssertionStore) result.get(0); - Object data = SerializationUtils.deserialize(element.getAssertion()); - + AssertionStore element = (AssertionStore) o; + Object data = SerializationUtils.deserialize(element.getAssertion()); + if (data instanceof SLOInformationContainer) { ISLOInformationContainer sloContainer = (ISLOInformationContainer) data; - + //check status sloBuilder.checkStatusCode(sloContainer, logOutResp); - + if (sloContainer.hasFrontChannelOA()) { try { //some response are open byte[] serializedSLOContainer = SerializationUtils.serialize((Serializable) sloContainer); element.setAssertion(serializedSLOContainer); element.setType(sloContainer.getClass().getName()); - - session.saveOrUpdate(element); - tx.commit(); - + + // session.saveOrUpdate(element); + // tx.commit(); + Logger.debug("Current Thread putAssertionStore: "+Thread.currentThread().getId()); + transactionStorage.putAssertionStore(element); + //sloContainer could be stored to database storageSuccess = true; - - } catch(HibernateException e) { - tx.rollback(); + + } catch(MOADatabaseException e) { + //tx.rollback(); counter++; Logger.debug("SLOContainter could not stored to database. Wait some time and restart storage process ... "); java.util.Random rand = new java.util.Random(); - + try { Thread.sleep(rand.nextInt(20)*10); - + } catch (InterruptedException e1) { Logger.warn("Thread could not stopped. ReStart storage process immediately", e1); } } - + } else { - //last response received. - try { - session.delete(element); - tx.commit(); - - } catch(HibernateException e) { - tx.rollback(); - Logger.error("SLOContainter could not deleted from database. "); - - } - + Logger.debug("Current Thread removeElement by Artifact: "+Thread.currentThread().getId()); + transactionStorage.remove(element.getArtifact()); + // session.delete(element); + // tx.commit(); + storageSuccess = true; String redirectURL = null; if (sloContainer.getSloRequest() != null) { @@ -237,70 +236,72 @@ public class SingleLogOutAction implements IAction { SingleLogoutService sloService = sloBuilder.getResponseSLODescriptor(sloContainer.getSloRequest()); LogoutResponse message = sloBuilder.buildSLOResponseMessage(sloService, sloContainer.getSloRequest(), sloContainer.getSloFailedOAs()); redirectURL = sloBuilder.getFrontChannelSLOMessageURL(sloService, message, httpReq, httpResp, sloContainer.getSloRequest().getRequest().getRelayState()); - + } else { //print SLO information directly redirectURL = req.getAuthURL() + "/idpSingleLogout"; - + String artifact = Random.nextRandom(); - - String statusCode = null; + + String statusCode = null; if (sloContainer.getSloFailedOAs() == null || - sloContainer.getSloFailedOAs().size() == 0) { - statusCode = MOAIDAuthConstants.SLOSTATUS_SUCCESS; - revisionsLogger.logEvent(sloContainer.getSessionID(), sloContainer.getTransactionID(), - MOAIDEventConstants.AUTHPROCESS_SLO_ALL_VALID); - + sloContainer.getSloFailedOAs().size() == 0) { + statusCode = MOAIDAuthConstants.SLOSTATUS_SUCCESS; + revisionsLogger.logEvent(sloContainer.getSessionID(), sloContainer.getTransactionID(), + MOAIDEventConstants.AUTHPROCESS_SLO_ALL_VALID); + } else { revisionsLogger.logEvent(sloContainer.getSessionID(), sloContainer.getTransactionID(), MOAIDEventConstants.AUTHPROCESS_SLO_NOT_ALL_VALID); - statusCode = MOAIDAuthConstants.SLOSTATUS_ERROR; - + statusCode = MOAIDAuthConstants.SLOSTATUS_ERROR; + } - transactionStorage.put(artifact, statusCode); - redirectURL = addURLParameter(redirectURL, MOAIDAuthConstants.PARAM_SLOSTATUS, artifact); - + transactionStorage.put(artifact, statusCode, -1); + redirectURL = addURLParameter(redirectURL, MOAIDAuthConstants.PARAM_SLOSTATUS, artifact); + } //redirect to Redirect Servlet String url = req.getAuthURL() + "/RedirectServlet"; url = addURLParameter(url, RedirectServlet.REDIRCT_PARAM_URL, URLEncoder.encode(redirectURL, "UTF-8")); url = httpResp.encodeRedirectURL(url); - + httpResp.setContentType("text/html"); httpResp.setStatus(302); httpResp.addHeader("Location", url); - + } } else { Logger.warn("Sessioninformation Cast-Exception by using Artifact=" + relayState); throw new MOADatabaseException("Sessioninformation Cast-Exception"); - + } } - - } catch (MOADatabaseException e) { - Logger.error("MOA AssertionDatabase ERROR", e); - throw new SLOException("pvp2.19", null); - - } catch (UnsupportedEncodingException e) { - Logger.error("Finale SLO redirct not possible.", e); - throw new AuthenticationException("pvp2.13", new Object[]{}); - - } finally { - if (tx != null && !tx.getStatus().equals(TransactionStatus.COMMITTED)) { - tx.commit(); - - } } - - - - } else { - Logger.error("Process SingleLogOutAction but request is NOT of type LogoutRequest or LogoutResponse."); - throw new MOAIDException("pvp2.13", null); - - } - + } catch (MOADatabaseException e) { + Logger.error("MOA AssertionDatabase ERROR", e); + throw new SLOException("pvp2.19", null); + + } catch (UnsupportedEncodingException e) { + Logger.error("Finale SLO redirct not possible.", e); + throw new AuthenticationException("pvp2.13", new Object[]{}); + + } + + // finally { + // if (tx != null && !tx.getStatus().equals(TransactionStatus.COMMITTED)) { + // tx.commit(); + // + // } + // } + + + + } else { + Logger.error("Process SingleLogOutAction but request is NOT of type LogoutRequest or LogoutResponse."); + throw new MOAIDException("pvp2.13", null); + + } + return null; } @@ -320,7 +321,7 @@ public class SingleLogOutAction implements IAction { public String getDefaultActionName() { return PVP2XProtocol.SINGLELOGOUT; } - + protected static String addURLParameter(String url, String paramname, String paramvalue) { String param = paramname + "=" + paramvalue; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java index 25b22f0ad..94d91694a 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java @@ -62,6 +62,7 @@ import at.gv.egovernment.moa.util.MiscUtil; public class SoapBinding implements IDecoder, IEncoder { + @Autowired(required=true) private MOAMetadataProvider metadataProvider; @Autowired private IDPCredentialProvider credentialProvider; public InboundMessageInterface decode(HttpServletRequest req, @@ -109,7 +110,7 @@ public class SoapBinding implements IDecoder, IEncoder { RequestAbstractType attributeRequest = (RequestAbstractType) attrReq; try { if (MiscUtil.isNotEmpty(attributeRequest.getIssuer().getValue()) && - MOAMetadataProvider.getInstance().getRole( + metadataProvider.getRole( attributeRequest.getIssuer().getValue(), SPSSODescriptor.DEFAULT_ELEMENT_NAME) != null) request.setEntityID(attributeRequest.getIssuer().getValue()); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPMetadataBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPMetadataBuilder.java index 855925272..e2f8664d8 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPMetadataBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPMetadataBuilder.java @@ -24,8 +24,6 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.builder; import java.io.IOException; import java.io.StringWriter; -import java.security.PrivateKey; -import java.security.interfaces.RSAPrivateKey; import java.util.List; import javax.xml.parsers.DocumentBuilder; @@ -66,7 +64,6 @@ import org.opensaml.xml.security.credential.UsageType; import org.opensaml.xml.security.keyinfo.KeyInfoGenerator; import org.opensaml.xml.security.x509.X509KeyInfoGeneratorFactory; import org.opensaml.xml.signature.Signature; -import org.opensaml.xml.signature.SignatureConstants; import org.opensaml.xml.signature.SignatureException; import org.opensaml.xml.signature.Signer; import org.springframework.stereotype.Service; @@ -74,6 +71,7 @@ import org.w3c.dom.Document; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.protocols.pvp2x.config.IPVPMetadataBuilderConfiguration; +import at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException; import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; import at.gv.egovernment.moa.logging.Logger; @@ -153,7 +151,7 @@ public class PVPMetadataBuilder { //set metadata signature parameters Credential metadataSignCred = config.getMetadataSigningCredentials(); - Signature signature = getIDPSignature(metadataSignCred); + Signature signature = AbstractCredentialProvider.getIDPSignature(metadataSignCred); SecurityHelper.prepareSignatureParams(signature, metadataSignCred, null, null); @@ -437,27 +435,5 @@ public class PVPMetadataBuilder { return idpSSODescriptor; } - - private Signature getIDPSignature(Credential credentials) { - PrivateKey privatekey = credentials.getPrivateKey(); - Signature signer = SAML2Utils.createSAMLObject(Signature.class); - if (privatekey instanceof RSAPrivateKey) { - signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); - - } else if (privatekey instanceof iaik.security.ecc.ecdsa.ECPrivateKey) { - signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA1); - - } else { - Logger.warn("Could NOT evaluate the Private-Key type from " + credentials.getEntityId() + " credential."); - - - } - - signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); - signer.setSigningCredential(credentials); - return signer; - - } - } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java index e5c897aa6..de59e6055 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java @@ -94,8 +94,9 @@ import at.gv.egovernment.moa.logging.Logger; @Service("PVP_SingleLogOutBuilder") public class SingleLogOutBuilder { + @Autowired(required=true) private MOAMetadataProvider metadataProvider; @Autowired private IDPCredentialProvider credentialProvider; - + public void checkStatusCode(ISLOInformationContainer sloContainer, LogoutResponse logOutResp) { Status status = logOutResp.getStatus(); if (!status.getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { @@ -353,7 +354,7 @@ public class SingleLogOutBuilder { public SingleLogoutService getRequestSLODescriptor(String entityID) throws NOSLOServiceDescriptorException { try { - EntityDescriptor entity = MOAMetadataProvider.getInstance().getEntityDescriptor(entityID); + EntityDescriptor entity = metadataProvider.getEntityDescriptor(entityID); SSODescriptor spsso = entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS); SingleLogoutService sloService = null; @@ -394,7 +395,7 @@ public class SingleLogOutBuilder { public SingleLogoutService getResponseSLODescriptor(PVPTargetConfiguration spRequest) throws NoMetadataInformationException, NOSLOServiceDescriptorException { MOARequest moaReq = (MOARequest) spRequest.getRequest(); - EntityDescriptor metadata = moaReq.getEntityMetadata(); + EntityDescriptor metadata = moaReq.getEntityMetadata(metadataProvider); SSODescriptor ssodesc = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS); if (ssodesc == null) { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java index 200429093..55d8fa1ff 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java @@ -459,8 +459,15 @@ public class PVP2AssertionBuilder implements PVPConstants { subjectConfirmationData.setNotOnOrAfter(new DateTime(authData.getSsoSessionValidTo().getTime())); // subjectConfirmationData.setNotBefore(date); + //set 'recipient' attribute in subjectConformationData subjectConfirmationData.setRecipient(assertionConsumerService.getLocation()); + //set IP address of the user machine as 'Address' attribute in subjectConformationData + String usersIPAddress = pendingReq.getGenericData( + PVPTargetConfiguration.DATAID_REQUESTER_IP_ADDRESS, String.class); + if (MiscUtil.isNotEmpty(usersIPAddress)) + subjectConfirmationData.setAddress(usersIPAddress); + //set SLO information sloInformation.setUserNameIdentifier(subjectNameID.getValue()); sloInformation.setNameIDFormat(subjectNameID.getFormat()); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/InboundMessage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/InboundMessage.java index 332caf967..8c8345bbf 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/InboundMessage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/InboundMessage.java @@ -25,11 +25,11 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.messages; import java.io.Serializable; import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.saml2.metadata.provider.MetadataProviderException; import org.w3c.dom.Element; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NoMetadataInformationException; -import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; import at.gv.egovernment.moa.logging.Logger; /** @@ -46,10 +46,12 @@ public class InboundMessage implements InboundMessageInterface, Serializable{ private String relayState = null; - public EntityDescriptor getEntityMetadata() throws NoMetadataInformationException { - + public EntityDescriptor getEntityMetadata(MetadataProvider metadataProvider) throws NoMetadataInformationException { try { - return MOAMetadataProvider.getInstance().getEntityDescriptor(this.entityID); + if (metadataProvider == null) + throw new NullPointerException("No PVP MetadataProvider found."); + + return metadataProvider.getEntityDescriptor(this.entityID); } catch (MetadataProviderException e) { Logger.warn("No Metadata for EntitiyID " + entityID); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java index 3002ca179..19adfe4c4 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java @@ -44,13 +44,14 @@ import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.saml2.metadata.provider.MetadataProviderException; import org.opensaml.saml2.metadata.provider.ObservableMetadataProvider; import org.opensaml.xml.XMLObject; +import org.springframework.stereotype.Service; +import at.gv.egovernment.moa.id.auth.IDestroyableObject; +import at.gv.egovernment.moa.id.auth.IGarbageCollectorProcessing; import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; -import at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing; -import at.gv.egovernment.moa.id.config.auth.MOAGarbageCollector; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.InterfederatedIDPPublicServiceFilter; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.PVPMetadataFilterChain; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.SchemaValidationFilter; @@ -58,65 +59,85 @@ import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.Base64Utils; import at.gv.egovernment.moa.util.MiscUtil; +@Service("PVPMetadataProvider") public class MOAMetadataProvider extends SimpleMOAMetadataProvider - implements ObservableMetadataProvider, IGarbageCollectorProcessing, IMOARefreshableMetadataProvider { + implements ObservableMetadataProvider, IGarbageCollectorProcessing, + IMOARefreshableMetadataProvider, IDestroyableObject { - private static MOAMetadataProvider instance = null; + //private static final int METADATA_GARBAGE_TIMEOUT_SEC = 604800; //7 days + +// private static MOAMetadataProvider instance = null; + MetadataProvider internalProvider = null; private static Object mutex = new Object(); + //private Map<String, Date> lastAccess = null; - public static MOAMetadataProvider getInstance() { - if (instance == null) { - synchronized (mutex) { - if (instance == null) { - instance = new MOAMetadataProvider(); - - //add this to MOA garbage collector - MOAGarbageCollector.addModulForGarbageCollection(instance); - - } - } - } - return instance; + public MOAMetadataProvider() { + internalProvider = new ChainingMetadataProvider(); + //lastAccess = new HashMap<String, Date>(); + } +// public static MOAMetadataProvider getInstance() { +// if (instance == null) { +// synchronized (mutex) { +// if (instance == null) { +// instance = new MOAMetadataProvider(); +// +// //add this to MOA garbage collector +// MOAGarbageCollector.addModulForGarbageCollection(instance); +// +// } +// } +// } +// return instance; +// } + /* (non-Javadoc) * @see at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing#runGarbageCollector() */ @Override public void runGarbageCollector() { - reInitialize(); - - } - - private static void reInitialize() { synchronized (mutex) { /**add new Metadataprovider or remove Metadataprovider which are not in use any more.**/ - if (instance != null) - try { - Logger.trace("Check consistence of PVP2X metadata"); - instance.addAndRemoveMetadataProvider(); + try { + Logger.trace("Check consistence of PVP2X metadata"); + addAndRemoveMetadataProvider(); - } catch (ConfigurationException e) { - Logger.error("Access to MOA-ID configuration FAILED.", e); + } catch (ConfigurationException e) { + Logger.error("Access to MOA-ID configuration FAILED.", e); - } - else - Logger.info("MOAMetadataProvider is not loaded."); + } } + } - public static void destroy() { - if (instance != null) { - instance.internalDestroy(); + +// private static void reInitialize() { +// synchronized (mutex) { +// +// /**add new Metadataprovider or remove Metadataprovider which are not in use any more.**/ +// if (instance != null) +// try { +// Logger.trace("Check consistence of PVP2X metadata"); +// instance.addAndRemoveMetadataProvider(); +// +// } catch (ConfigurationException e) { +// Logger.error("Access to MOA-ID configuration FAILED.", e); +// +// } +// else +// Logger.info("MOAMetadataProvider is not loaded."); +// } +// } + + public void fullyDestroy() { + internalDestroy(); - } else { - Logger.info("MOAMetadataProvider is not loaded. Accordingly it can not be destroyed"); - } } - MetadataProvider internalProvider; + @Override public boolean refreshMetadataProvider(String entityID) { @@ -208,7 +229,7 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider private void addAndRemoveMetadataProvider() throws ConfigurationException { if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) { - Logger.info("Relaod MOAMetaDataProvider."); + Logger.info("Reload MOAMetaDataProvider."); /*OpenSAML ChainingMetadataProvider can not remove a MetadataProvider (UnsupportedOperationException) *The ChainingMetadataProvider use internal a unmodifiableList to hold all registrated MetadataProviders.*/ @@ -217,7 +238,19 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider //get all actually loaded metadata providers Map<String, HTTPMetadataProvider> loadedproviders = getAllActuallyLoadedProviders(); - + + /* TODO: maybe add metadata provider destroy after timeout. + * But could be a problem if one Metadataprovider load an EntitiesDescriptor + * with more the multiple EntityDescriptors. If one of this EntityDesciptors + * are expired the full EntitiesDescriptor is removed. + * + * Timeout requires a better solution in this case! + */ +// Date now = new Date(); +// Date expioredate = new Date(now.getTime() - (METADATA_GARBAGE_TIMEOUT_SEC * 1000)); +// Logger.debug("Starting PVP Metadata garbag collection (Expioredate:" +// + expioredate + ")"); + //load all PVP2 OAs form ConfigurationDatabase and //compare actually loaded Providers with configured PVP2 OAs Map<String, String> allOAs = AuthConfigurationProviderFactory.getInstance().getConfigurationWithWildCard( @@ -238,30 +271,31 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider HTTPMetadataProvider httpProvider = null; try { if (MiscUtil.isNotEmpty(metadataurl)) { - if (loadedproviders.containsKey(metadataurl)) { + if (loadedproviders.containsKey(metadataurl)) { // PVP2 OA is actually loaded, to nothing providersinuse.put(metadataurl, loadedproviders.get(metadataurl)); loadedproviders.remove(metadataurl); - } else if ( MiscUtil.isNotEmpty(metadataurl) && - !providersinuse.containsKey(metadataurl) ) { - //PVP2 OA is new, add it to MOAMetadataProvider - String certBase64 = oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_PVP2X_CERTIFICATE); - if (MiscUtil.isNotEmpty(certBase64)) { - byte[] cert = Base64Utils.decode(certBase64, false); - String oaFriendlyName = oaParam.getFriendlyName(); - - - Logger.info("Loading metadata for: " + oaFriendlyName); - httpProvider = createNewHTTPMetaDataProvider( - metadataurl, - buildMetadataFilterChain(oaParam, metadataurl, cert), - oaFriendlyName); - - if (httpProvider != null) - providersinuse.put(metadataurl, httpProvider); - } + //INFO: load metadata dynamically if they are requested +// } else if ( MiscUtil.isNotEmpty(metadataurl) && +// !providersinuse.containsKey(metadataurl) ) { +// //PVP2 OA is new, add it to MOAMetadataProvider +// String certBase64 = oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_PVP2X_CERTIFICATE); +// if (MiscUtil.isNotEmpty(certBase64)) { +// byte[] cert = Base64Utils.decode(certBase64, false); +// String oaFriendlyName = oaParam.getFriendlyName(); +// +// +// Logger.info("Loading metadata for: " + oaFriendlyName); +// httpProvider = createNewHTTPMetaDataProvider( +// metadataurl, +// buildMetadataFilterChain(oaParam, metadataurl, cert), +// oaFriendlyName); +// +// if (httpProvider != null) +// providersinuse.put(metadataurl, httpProvider); +// } } } @@ -339,15 +373,21 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider } } - instance = null; + internalProvider = new ChainingMetadataProvider(); } else { Logger.warn("ReInitalize MOAMetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy"); } } - private MOAMetadataProvider() { + @Deprecated + /** + * Load all PVP metadata from OA configuration + * + * This method is deprecated because OA metadata should be loaded dynamically + * if the corresponding OA is requested. + */ + private void loadAllPVPMetadataFromKonfiguration() { ChainingMetadataProvider chainProvider = new ChainingMetadataProvider(); - Logger.info("Loading metadata"); Map<String, MetadataProvider> providersinuse = new HashMap<String, MetadataProvider>(); try { @@ -417,14 +457,15 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider + e.getMessage(), e); } + internalProvider = chainProvider; + } catch (ConfigurationException e) { Logger.error("Access MOA-ID configuration FAILED.", e); } - - internalProvider = chainProvider; + } - + private PVPMetadataFilterChain buildMetadataFilterChain(IOAAuthParameters oaParam, String metadataURL, byte[] certificate) throws CertificateException { PVPMetadataFilterChain filterChain = new PVPMetadataFilterChain(metadataURL, certificate); filterChain.getFilters().add(new SchemaValidationFilter()); @@ -505,17 +546,30 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider } +// if (entityDesc != null) +// lastAccess.put(entityID, new Date()); + return entityDesc; } public List<RoleDescriptor> getRole(String entityID, QName roleName) - throws MetadataProviderException { - return internalProvider.getRole(entityID, roleName); + throws MetadataProviderException { + List<RoleDescriptor> result = internalProvider.getRole(entityID, roleName); + +// if (result != null) +// lastAccess.put(entityID, new Date()); + + return result; } public RoleDescriptor getRole(String entityID, QName roleName, String supportedProtocol) throws MetadataProviderException { - return internalProvider.getRole(entityID, roleName, supportedProtocol); + RoleDescriptor result = internalProvider.getRole(entityID, roleName, supportedProtocol); + +// if (result != null) +// lastAccess.put(entityID, new Date()); + + return result; } /* (non-Javadoc) diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java index 442455d4b..8261a86c1 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java @@ -81,7 +81,7 @@ public abstract class SimpleMOAMetadataProvider implements MetadataProvider{ } } - timer = new Timer(); + timer = new Timer(true); httpProvider = new HTTPMetadataProvider(timer, httpClient, metadataURL); httpProvider.setParserPool(new BasicParserPool()); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/signer/AbstractCredentialProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/signer/AbstractCredentialProvider.java index bf4cfd480..77cc7228b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/signer/AbstractCredentialProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/signer/AbstractCredentialProvider.java @@ -24,6 +24,7 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.signer; import java.security.KeyStore; import java.security.PrivateKey; +import java.security.interfaces.ECPrivateKey; import java.security.interfaces.RSAPrivateKey; import org.opensaml.xml.security.credential.Credential; @@ -198,7 +199,7 @@ public abstract class AbstractCredentialProvider { if (privatekey instanceof RSAPrivateKey) { signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); - } else if (privatekey instanceof iaik.security.ecc.ecdsa.ECPrivateKey) { + } else if (privatekey instanceof ECPrivateKey) { signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA1); } else { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java index f384dd511..f6104bdeb 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java @@ -41,6 +41,7 @@ import org.opensaml.xml.security.criteria.EntityIDCriteria; import org.opensaml.xml.security.criteria.UsageCriteria; import org.opensaml.xml.signature.SignatureTrustEngine; import org.opensaml.xml.validation.ValidationException; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.w3c.dom.Element; import org.xml.sax.SAXException; @@ -56,6 +57,8 @@ import at.gv.egovernment.moa.util.MiscUtil; @Service("SAMLVerificationEngine") public class SAMLVerificationEngine { + + @Autowired(required=true) MOAMetadataProvider metadataProvider; public void verify(InboundMessage msg, SignatureTrustEngine sigTrustEngine ) throws org.opensaml.xml.security.SecurityException, Exception { try { @@ -72,7 +75,8 @@ public class SAMLVerificationEngine { } Logger.debug("PVP2X message validation FAILED. Relead metadata for entityID: " + msg.getEntityID()); - if (!MOAMetadataProvider.getInstance().refreshMetadataProvider(msg.getEntityID())) + + if (metadataProvider == null || !metadataProvider.refreshMetadataProvider(msg.getEntityID())) throw e; else { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/MOASPMetadataSignatureFilter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/MOASPMetadataSignatureFilter.java index 3d69b0380..6e97913bf 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/MOASPMetadataSignatureFilter.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/MOASPMetadataSignatureFilter.java @@ -102,6 +102,7 @@ public class MOASPMetadataSignatureFilter implements MetadataFilter { } + Logger.debug("SAML metadata for entityID:" + entityDes.getEntityID() + " is valid"); } catch (MOAIDException | TransformerFactoryConfigurationError | TransformerException | IOException e) { Logger.error("Metadata verification has an interal error.", e); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBAuthenticationSessionStoreage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBAuthenticationSessionStoreage.java index 094e25040..4d7936f25 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBAuthenticationSessionStoreage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBAuthenticationSessionStoreage.java @@ -35,6 +35,7 @@ import org.hibernate.Transaction; import org.hibernate.resource.transaction.spi.TransactionStatus; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import com.fasterxml.jackson.core.JsonProcessingException; @@ -65,7 +66,7 @@ import at.gv.egovernment.moa.util.MiscUtil; public class DBAuthenticationSessionStoreage implements IAuthenticationSessionStoreage{ @Autowired AuthConfiguration authConfig; - + @Autowired MOASessionDBUtils moaSessionDBUtils; private static JsonMapper mapper = new JsonMapper(); @Override @@ -74,7 +75,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt AuthenticatedSessionStore session; try { - session = searchInDatabase(moaSessionID, true); + session = searchInDatabase(moaSessionID); return session.isAuthenticated(); } catch (MOADatabaseException e) { @@ -104,7 +105,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt encryptSession(session, dbsession); //store AssertionStore element to Database - MOASessionDBUtils.saveOrUpdate(dbsession); + moaSessionDBUtils.saveOrUpdate(dbsession); Logger.info("Create MOASession with sessionID: " + id); return session; @@ -128,7 +129,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt return null; try { - AuthenticatedSessionStore dbsession = searchInDatabase(sessionID, true); + AuthenticatedSessionStore dbsession = searchInDatabase(sessionID); return decryptSession(dbsession); } catch (MOADatabaseException e) { @@ -143,7 +144,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt @Override public AuthenticationSessionExtensions getAuthenticationSessionExtensions(String sessionID) throws MOADatabaseException { - AuthenticatedSessionStore dbsession = searchInDatabase(sessionID, true); + AuthenticatedSessionStore dbsession = searchInDatabase(sessionID); if (MiscUtil.isNotEmpty(dbsession.getAdditionalInformation())) { try { @@ -161,12 +162,12 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt @Override public void setAuthenticationSessionExtensions(String sessionID, AuthenticationSessionExtensions sessionExtensions) throws MOADatabaseException { try { - AuthenticatedSessionStore dbsession = searchInDatabase(sessionID, true); + AuthenticatedSessionStore dbsession = searchInDatabase(sessionID); dbsession.setAdditionalInformation( mapper.serialize(sessionExtensions)); - MOASessionDBUtils.saveOrUpdate(dbsession); + moaSessionDBUtils.saveOrUpdate(dbsession); Logger.debug("MOASession with sessionID=" + sessionID + " is stored in Database"); @@ -185,7 +186,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt @Override public void storeSession(AuthenticationSession session) throws MOADatabaseException, BuildException { try { - AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID(), true); + AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID()); encryptSession(session, dbsession); @@ -193,7 +194,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt dbsession.setAuthenticated(session.isAuthenticated()); dbsession.setUpdated(new Date()); - MOASessionDBUtils.saveOrUpdate(dbsession); + moaSessionDBUtils.saveOrUpdate(dbsession); Logger.debug("MOASession with sessionID=" + session.getSessionID() + " is stored in Database"); } catch (MOADatabaseException e) { @@ -205,7 +206,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt @Override public void destroySession(String moaSessionID) throws MOADatabaseException { - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); List<AuthenticatedSessionStore> result; Transaction tx = null; @@ -216,6 +217,8 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt Query query = session.getNamedQuery("getSessionWithID"); query.setParameter("sessionid", moaSessionID); result = query.list(); + + Logger.trace("Found entries: " + result.size()); @@ -243,7 +246,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt @Override public String changeSessionID(AuthenticationSession session, String newSessionID) throws BuildException, MOADatabaseException { - AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID(), true); + AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID()); Logger.debug("Change SessionID from " + session.getSessionID() + "to " + newSessionID); @@ -257,7 +260,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt //set Timestamp in this state, because automated timestamp generation is buggy in Hibernate 4.2.1 dbsession.setUpdated(new Date()); - MOASessionDBUtils.saveOrUpdate(dbsession); + moaSessionDBUtils.saveOrUpdate(dbsession); Logger.trace("Change SessionID complete."); @@ -279,9 +282,9 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt AuthenticatedSessionStore session; try { - session = searchInDatabase(moaSessionID, true); + session = searchInDatabase(moaSessionID); session.setAuthenticated(isAuthenticated); - MOASessionDBUtils.saveOrUpdate(session); + moaSessionDBUtils.saveOrUpdate(session); } catch (MOADatabaseException e) { @@ -293,7 +296,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt public String getMOASessionSSOID(String SSOSessionID) { MiscUtil.assertNotNull(SSOSessionID, "SSOsessionID"); Logger.trace("Get authenticated session with SSOID " + SSOSessionID + " from database."); - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); List<AuthenticatedSessionStore> result; Transaction tx = null; @@ -331,7 +334,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt @Override public boolean isSSOSession(String sessionID) throws MOADatabaseException { try { - AuthenticatedSessionStore dbsession = searchInDatabase(sessionID, true); + AuthenticatedSessionStore dbsession = searchInDatabase(sessionID); return dbsession.isSSOSession(); } catch (MOADatabaseException e) { @@ -346,7 +349,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt //TODO: is this method really needed?? MiscUtil.assertNotNull(SSOId, "SSOSessionID"); Logger.trace("Get authenticated session with SSOID " + SSOId + " from database."); - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); List<AuthenticatedSessionStore> result; Transaction tx = null; @@ -387,7 +390,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt try { - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); List<AuthenticatedSessionStore> result; Logger.trace("Add SSO information to session " + moaSessionID); @@ -487,63 +490,63 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt @Override public List<OASessionStore> getAllActiveOAFromMOASession(AuthenticationSession moaSession) { MiscUtil.assertNotNull(moaSession, "MOASession"); - Session session = null; - - try { - List<OASessionStore> oas = new ArrayList<OASessionStore>(); - - AuthenticatedSessionStore dbsession = searchInDatabase(moaSession.getSessionID(), false); - oas.addAll(dbsession.getActiveOAsessions()); - - session = MOASessionDBUtils.getCurrentSession(); - session.getTransaction().commit(); - - return oas; - - } catch (MOADatabaseException e) { - Logger.warn("NO session information found for sessionID " + moaSession.getSessionID(), e); - - } catch (Exception e) { - if (session != null && session.getTransaction() != null - && !session.getTransaction().getStatus().equals(TransactionStatus.COMMITTED)) { - session.getTransaction().rollback(); - throw e; - - } - - } - - return null; + + Logger.trace("Get OAs for moaSession " + moaSession.getSessionID() + " from database."); + Session session = moaSessionDBUtils.getCurrentSession(); + + List<OASessionStore> result; + Transaction tx = null; + try { + synchronized (session) { + tx = session.beginTransaction(); + Query query = session.getNamedQuery("getAllActiveOAsForSessionID"); + query.setParameter("sessionID", moaSession.getSessionID()); + result = query.list(); + + //send transaction + tx.commit(); + } + + Logger.trace("Found entries: " + result.size()); + + return result; + + } catch (Exception e) { + if (tx != null && !tx.getStatus().equals(TransactionStatus.COMMITTED)) + tx.rollback(); + throw e; + } } @Override public List<InterfederationSessionStore> getAllActiveIDPsFromMOASession(AuthenticationSession moaSession) { MiscUtil.assertNotNull(moaSession, "MOASession"); - Session session = null; - try { - List<InterfederationSessionStore> idps = new ArrayList<InterfederationSessionStore>(); - AuthenticatedSessionStore dbsession = searchInDatabase(moaSession.getSessionID(), false); - idps.addAll(dbsession.getInderfederation()); - - session = MOASessionDBUtils.getCurrentSession(); - session.getTransaction().commit(); - - return idps; - - } catch (MOADatabaseException e) { - Logger.warn("NO session information found for sessionID " + moaSession.getSessionID(), e); - - } catch (Exception e) { - if (session != null && session.getTransaction() != null - && !session.getTransaction().getStatus().equals(TransactionStatus.COMMITTED)) { - session.getTransaction().rollback(); - throw e; - - } - - } - - return null; + + Logger.trace("Get active IDPs for moaSession " + moaSession.getSessionID() + " from database."); + Session session = moaSessionDBUtils.getCurrentSession(); + + List<InterfederationSessionStore> result; + Transaction tx = null; + try { + synchronized (session) { + tx = session.beginTransaction(); + Query query = session.getNamedQuery("getAllActiveIDPsForSessionID"); + query.setParameter("sessionID", moaSession.getSessionID()); + result = query.list(); + + //send transaction + tx.commit(); + } + + Logger.trace("Found entries: " + result.size()); + + return result; + + } catch (Exception e) { + if (tx != null && !tx.getStatus().equals(TransactionStatus.COMMITTED)) + tx.rollback(); + throw e; + } } @Override @@ -552,7 +555,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt MiscUtil.assertNotNull(userNameID, "userNameID"); Logger.trace("Get moaSession for userNameID " + userNameID + " and OA " + oaID + " from database."); - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); Transaction tx = null; List<AuthenticatedSessionStore> result = null;; @@ -598,7 +601,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt MiscUtil.assertNotNull(protocolType, "usedProtocol"); Logger.trace("Get active OnlineApplication for sessionID " + moaSession.getSessionID() + " with OAID " + oaID + " from database."); - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); List<AuthenticatedSessionStore> result; Transaction tx = null; @@ -640,7 +643,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt try { MiscUtil.assertNotNull(nameID, "nameID"); Logger.trace("Get authenticated session with pedingRequestID " + nameID + " from database."); - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); List<AuthenticatedSessionStore> result; @@ -677,7 +680,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt public InterfederationSessionStore searchInterfederatedIDPFORSSOWithMOASession(String sessionID) { MiscUtil.assertNotNull(sessionID, "MOASession"); Logger.trace("Get interfederated IDP for SSO with sessionID " + sessionID + " from database."); - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); List<AuthenticatedSessionStore> result; Transaction tx = null; @@ -714,7 +717,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt MiscUtil.assertNotNull(sessionID, "MOASession"); MiscUtil.assertNotNull(idpID, "Interfederated IDP ID"); Logger.trace("Get interfederated IDP "+ idpID + " for SSO with sessionID " + sessionID + " from database."); - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); List<AuthenticatedSessionStore> result; Transaction tx = null; @@ -756,7 +759,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt String moaSession = getMOASessionSSOID(req.getMOASessionIdentifier()); if (MiscUtil.isNotEmpty(moaSession)) { try { - dbsession = searchInDatabase(moaSession, true); + dbsession = searchInDatabase(moaSession); }catch (MOADatabaseException e) { Logger.error("NO MOASession found but MOASession MUST already exist!"); @@ -818,7 +821,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt //store AssertionStore element to Database try { - MOASessionDBUtils.saveOrUpdate(dbsession); + moaSessionDBUtils.saveOrUpdate(dbsession); } catch (MOADatabaseException e) { Logger.warn("MOASession could not be created."); @@ -831,7 +834,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt public InterfederationSessionStore searchInterfederatedIDPFORAttributeQueryWithSessionID(String moaSessionID) { MiscUtil.assertNotNull(moaSessionID, "MOASessionID"); Logger.trace("Get interfederated IDP for AttributeQuery with sessionID " + moaSessionID + " from database."); - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); List<AuthenticatedSessionStore> result; Transaction tx = null; @@ -872,7 +875,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt MiscUtil.assertNotNull(pedingRequestID, "pedingRequestID"); Logger.trace("Get authenticated session with pedingRequestID " + pedingRequestID + " from database."); - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); List<AuthenticatedSessionStore> result; @@ -907,7 +910,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt } } - MOASessionDBUtils.saveOrUpdate(authsession); + moaSessionDBUtils.saveOrUpdate(authsession); return true; } catch (Throwable e) { @@ -922,7 +925,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt Date expioredateupdate = new Date(now.getTime() - authDataTimeOutUpdated); List<AuthenticatedSessionStore> results; - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); Transaction tx = null; try { synchronized (session) { @@ -972,26 +975,26 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt } - private static void cleanDelete(AuthenticatedSessionStore result) { + private void cleanDelete(AuthenticatedSessionStore result) { try { result.setSession("blank".getBytes()); - MOASessionDBUtils.saveOrUpdate(result); + moaSessionDBUtils.saveOrUpdate(result); } catch (MOADatabaseException e) { Logger.warn("Blank authenticated session with sessionID=" + result.getSessionid() + " FAILED.", e); } finally { - if (!MOASessionDBUtils.delete(result)) + if (!moaSessionDBUtils.delete(result)) Logger.error("Authenticated session with sessionID=" + result.getSessionid() + " not removed! (Error during Database communication)"); } } @SuppressWarnings("rawtypes") - private static AuthenticatedSessionStore searchInDatabase(String sessionID, boolean commit) throws MOADatabaseException { + private AuthenticatedSessionStore searchInDatabase(String sessionID) throws MOADatabaseException { MiscUtil.assertNotNull(sessionID, "moasessionID"); Logger.trace("Get authenticated session with sessionID " + sessionID + " from database."); - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = moaSessionDBUtils.getCurrentSession(); List result; Transaction tx = null; @@ -1003,8 +1006,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt result = query.list(); //send transaction - if (commit) - tx.commit(); + tx.commit(); } Logger.trace("Found entries: " + result.size()); @@ -1019,7 +1021,7 @@ public class DBAuthenticationSessionStoreage implements IAuthenticationSessionSt return (AuthenticatedSessionStore) result.get(0); } catch (Exception e) { - if (tx != null && !tx.getStatus().equals(TransactionStatus.COMMITTED) && commit) + if (tx != null && !tx.getStatus().equals(TransactionStatus.COMMITTED)) tx.rollback(); throw e; } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java index c2b3b0fc5..f17e4a99a 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/DBTransactionStorage.java @@ -27,24 +27,31 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.PersistenceException; +import javax.persistence.Query; + import org.apache.commons.lang.SerializationUtils; import org.hibernate.HibernateException; -import org.hibernate.Query; -import org.hibernate.Session; -import org.springframework.stereotype.Service; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; -import at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils; import at.gv.egovernment.moa.id.commons.db.dao.session.AssertionStore; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; -@Service("TransactionStorage") +@Repository +@Transactional("sessionTransactionManager") public class DBTransactionStorage implements ITransactionStorage { - + + @PersistenceContext(unitName="session") + private EntityManager entityManager; + public boolean containsKey(String key) { - try { + try { searchInDatabase(key); return true; @@ -73,7 +80,7 @@ public class DBTransactionStorage implements ITransactionStorage { } - public void put(String key, Object value) throws MOADatabaseException { + public void put(String key, Object value, int timeout_ms) throws MOADatabaseException { //search if key already exists AssertionStore element = searchInDatabase(key); @@ -97,7 +104,11 @@ public class DBTransactionStorage implements ITransactionStorage { Logger.error("This exeption should not occur!!!!", e); return null; - } + } + } + + public Object getAssertionStore(String key) throws MOADatabaseException{ + return searchInDatabase(key); } public Object get(String key) throws MOADatabaseException { @@ -151,16 +162,12 @@ public class DBTransactionStorage implements ITransactionStorage { List<AssertionStore> results; List<String> returnValues = new ArrayList<String>();; - Session session = MOASessionDBUtils.getCurrentSession(); - synchronized (session) { - session.beginTransaction(); - Query query = session.getNamedQuery("getAssertionWithTimeOut"); - query.setTimestamp("timeout", expioredate); - results = query.list(); - session.getTransaction().commit(); - } + Query query = entityManager.createNamedQuery("getAssertionWithTimeOut"); + query.setParameter("timeout", expioredate); + results = query.getResultList(); + if (results != null) { for (AssertionStore el : results) returnValues.add(el.getArtifact()); @@ -187,24 +194,21 @@ public class DBTransactionStorage implements ITransactionStorage { Logger.info("Sessioninformation not removed! (Message:"+ e.getMessage() + ")"); } catch (HibernateException e) { - Logger.warn("Sessioninformation not removed! (Error during Database communication)", e); + Logger.warn("Sessioninformation not removed! (Erreor during Database communication)", e); } } private void cleanDelete(AssertionStore element) { - try { - element.setAssertion("blank".getBytes()); - MOASessionDBUtils.saveOrUpdate(element); - - } catch (MOADatabaseException e) { - Logger.warn("Blank shortTime session with artifact=" + element.getArtifact() + " FAILED.", e); + - } finally { - if (!MOASessionDBUtils.delete(element)) + try{ + element.setAssertion("blank".getBytes()); + entityManager.merge(element); + entityManager.remove(element); + }catch(PersistenceException e){ Logger.error("ShortTime session with artifact=" + element.getArtifact() + " not removed! (Error during Database communication)"); - - } + } } @@ -212,29 +216,23 @@ public class DBTransactionStorage implements ITransactionStorage { private AssertionStore searchInDatabase(String artifact) throws MOADatabaseException { MiscUtil.assertNotNull(artifact, "artifact"); Logger.trace("Getting sessioninformation with ID " + artifact + " from database."); - Session session = MOASessionDBUtils.getCurrentSession(); - List result; + List<AssertionStore> results; - synchronized (session) { - session.beginTransaction(); - Query query = session.getNamedQuery("getAssertionWithArtifact"); - query.setParameter("artifact", artifact); - result = query.list(); + Query query = entityManager.createNamedQuery("getAssertionWithArtifact"); + query.setParameter("artifact", artifact); - //send transaction - session.getTransaction().commit(); - } + results = query.getResultList(); - Logger.trace("Found entries: " + result.size()); + Logger.trace("Found entries: " + results.size()); //Assertion requires an unique artifact - if (result.size() != 1) { + if (results.size() != 1) { Logger.debug("No transaction information with ID:" + artifact + " found."); return null; } - return (AssertionStore) result.get(0); + return results.get(0); } private void put(AssertionStore element, String key, Object value) throws MOADatabaseException { @@ -253,15 +251,23 @@ public class DBTransactionStorage implements ITransactionStorage { element.setAssertion(data); //store AssertionStore element to Database - try { - MOASessionDBUtils.saveOrUpdate(element); + //try { + entityManager.persist(element); + //MOASessionDBUtils.saveOrUpdate(element); Logger.debug(value.getClass().getName() + " with ID: " + key + " is stored in Database"); - - } catch (MOADatabaseException e) { - Logger.warn("Sessioninformation could not be stored."); - throw new MOADatabaseException(e); - - } +// +// } catch (MOADatabaseException e) { +// Logger.warn("Sessioninformation could not be stored."); +// throw new MOADatabaseException(e); +// +// } + + } + + @Override + public void putAssertionStore(Object element) throws MOADatabaseException{ + // TODO Auto-generated method stub + entityManager.merge(element); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/ITransactionStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/ITransactionStorage.java index 493f24ee8..53a7f4f5e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/ITransactionStorage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/ITransactionStorage.java @@ -48,9 +48,10 @@ public interface ITransactionStorage { * @param key Id which identifiers the data object * @param value Data object which should be stored. * This data must implement the <code>java.io.Serializable</code> interface + * @param timeout_ms Defines the period of time a data object is kept within the storage * @throws MOADatabaseException In case of store operation failed */ - public void put(String key, Object value) throws MOADatabaseException; + public void put(String key, Object value, int timeout_ms) throws MOADatabaseException; /** * Get a data object from transaction storage @@ -110,4 +111,21 @@ public interface ITransactionStorage { */ public List<String> clean(Date now, long dataTimeOut); + + /** + * Get whole AssertionStoreObject, required for SLO + * + * @param key key Id which identifiers the data object + * @return The transaction-data object, or null + * @throws MOADatabaseException In case of load operation failed + */ + public Object getAssertionStore(String key) throws MOADatabaseException; + + /** + * Put whole AssertionStoreObject to db, required for SLO + * + * @param element assertion store object + */ + public void putAssertionStore(Object element) throws MOADatabaseException; + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/RedisTransactionStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/RedisTransactionStorage.java new file mode 100644 index 000000000..c17bff358 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/RedisTransactionStorage.java @@ -0,0 +1,377 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + *******************************************************************************/ +package at.gv.egovernment.moa.id.storage; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.lang.SerializationUtils; +import org.hibernate.HibernateException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.data.redis.core.RedisOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.SessionCallback; +import org.springframework.data.redis.serializer.JacksonJsonRedisSerializer; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; +import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; +import at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils; +import at.gv.egovernment.moa.id.commons.db.dao.session.AssertionStore; +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; + +@Service("TransactionStorage") +public class RedisTransactionStorage implements ITransactionStorage { + + @Autowired + private RedisTemplate<String, Object> redisTemplate; + + @Autowired + protected AuthConfiguration authConfig; + + @Autowired + private JacksonJsonRedisSerializer assertionStoreSerializer; + + public RedisTemplate<String, Object> getTemplate(){ + return this.redisTemplate; + } + + public void setTemplate(RedisTemplate<String, Object> t){ + this.redisTemplate = t; + } + + public boolean containsKey(String key) { + try { + searchInDatabase(key); + return true; + + } catch (MOADatabaseException e) { + return false; + } + + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.storage.ITransactionStorage#changeKey(java.lang.String, java.lang.String, java.lang.Object) + */ + @Override + public void changeKey(String oldKey, String newKey, Object value) throws MOADatabaseException { + + //search if key already exists + final int expTime = redisTemplate.getExpire(oldKey, TimeUnit.MILLISECONDS).intValue(); + //AssertionStore element = searchInDatabase(oldKey); + if (expTime < 0) { + Logger.info("No transaction-data with oldKey:" + oldKey + + " found. Process gets stopped."); + throw new MOADatabaseException("No transaction-data with oldKey:" + oldKey + + " found. Process gets stopped."); + + } + + //Important: Rename not working here, because the new ID also has to be put into the + //value object. + //redisTemplate.rename(oldKey, newKey); + + final String old_key = oldKey; + + //redisTemplate.delete(oldKey); + //put(null, newKey, value, expTime); + final AssertionStore assertion = prepareAssertion(null, newKey, value); + List<Object> txResults = redisTemplate.execute(new SessionCallback<List<Object>>() { + public List<Object> execute(RedisOperations operations) throws DataAccessException { + operations.multi(); + operations.delete(old_key); + operations.opsForValue().set(assertion.getArtifact(), new String(assertionStoreSerializer.serialize(assertion)),expTime,TimeUnit.MILLISECONDS); + // This will contain the results of all ops in the transaction + return operations.exec(); + } + }); + + int a= txResults.size(); + } + + public void put(String key, Object value, int timeoutms) throws MOADatabaseException { + + //search if key already exists + AssertionStore element = searchInDatabase(key); + + //create a new entry if key does not exists already + if (element == null) { + element = new AssertionStore(); + + } + + put(element, key, value, timeoutms); + } + + public <T> T get(String key, + final Class<T> clazz) throws MOADatabaseException { + + try { + return get(key, clazz, -1); + + } catch (AuthenticationException e) { + //this execption only occurs if an additional timeOut is used + Logger.error("This exeption should not occur!!!!", e); + return null; + + } + } + + public Object get(String key) throws MOADatabaseException { + AssertionStore element = searchInDatabase(key); + + if (element == null) + return null; + + return SerializationUtils.deserialize(element.getAssertion()); + + + } + + public <T> T get(String key, final Class<T> clazz, long dataTimeOut) throws MOADatabaseException, AuthenticationException { + + AssertionStore element = searchInDatabase(key); + + if (element == null) + return null; + +// dataTimeOut = -1; +// if (dataTimeOut > -1) { +// //check timeout +// long now = new Date().getTime(); +// +// if (now - element.getDatatime().getTime() > dataTimeOut) { +// Logger.info("Transaction-Data with key: " + key + " is out of time."); +// throw new AuthenticationException("1207", new Object[] { key }); +// +// } +// } + + + //Deserialize Assertion + Object data = SerializationUtils.deserialize(element.getAssertion()); + + //check if assertion has the correct class type + try { + @SuppressWarnings("unchecked") + T test = (T) Class.forName(element.getType()).cast(data); + return test; + + } catch (Exception e) { + Logger.warn("Sessioninformation Cast-Exception by using Artifact=" + key); + throw new MOADatabaseException("Sessioninformation Cast-Exception"); + + } + } + + //NOT USED with REDIS + public List<String> clean(Date now, long dataTimeOut) { + + //redis enables to set TTL when creating new values, so we don't need this function anymore + +// Date expioredate = new Date(now.getTime() - dataTimeOut); +// +// List<AssertionStore> results; + List<String> returnValues = new ArrayList<String>(); +// Session session = MOASessionDBUtils.getCurrentSession(); +// +// synchronized (session) { +// session.beginTransaction(); +// Query query = session.getNamedQuery("getAssertionWithTimeOut"); +// query.setTimestamp("timeout", expioredate); +// results = query.list(); +// session.getTransaction().commit(); +// } +// +// if (results != null) { +// for (AssertionStore el : results) +// returnValues.add(el.getArtifact()); +// +// } + return returnValues; + } + + public void remove(String key) { + + try { + + AssertionStore element = searchInDatabase(key); + if (element == null) { + Logger.debug("Sessioninformation not removed! (Sessioninformation with ID=" + key + + "not found)"); + return; + } + + redisTemplate.delete(key); + //cleanDelete(element); + Logger.debug("Removed stored information with ID: " + key); + + + } catch (MOADatabaseException e) { + Logger.info("Sessioninformation not removed! (Message:"+ e.getMessage() + ")"); + + } catch (HibernateException e) { + Logger.warn("Sessioninformation not removed! (Error during Database communication)", e); + } + } + + //Not used within REDIS store + private void cleanDelete(AssertionStore element) { +// try { +// element.setAssertion("blank".getBytes()); +// MOASessionDBUtils.saveOrUpdate(element); +// +// } catch (MOADatabaseException e) { +// Logger.warn("Blank shortTime session with artifact=" + element.getArtifact() + " FAILED.", e); +// +// } finally { +// if (!MOASessionDBUtils.delete(element)) +// Logger.error("ShortTime session with artifact=" + element.getArtifact() +// + " not removed! (Error during Database communication)"); +// +// } + + } + + //name="getAssertionWithArtifact", query = "select assertionstore from AssertionStore assertionstore where assertionstore.artifact = :artifact"), + //@NamedQuery(name="getAssertionWithTimeOut", query = "select assertionstore from AssertionStore assertionstore where assertionstore.timestamp < :timeout") + + @SuppressWarnings("rawtypes") + private AssertionStore searchInDatabase(String artifact) throws MOADatabaseException { + MiscUtil.assertNotNull(artifact, "artifact"); + Logger.trace("Getting sessioninformation with ID " + artifact + " from database."); + + +// Session session = MOASessionDBUtils.getCurrentSession(); +// List result; +// +// synchronized (session) { +// session.beginTransaction(); +// Query query = session.getNamedQuery("getAssertionWithArtifact"); +// query.setParameter("artifact", artifact); +// result = query.list(); +// +// //send transaction +// session.getTransaction().commit(); +// } + //String id = (String) redisTemplate.opsForSet().pop(artifact); + String assertion = (String) redisTemplate.opsForValue().get(artifact); + //String id = (String) redisTemplate.opsForValue().get(artifact); + if(assertion == null){ + Logger.debug("No transaction information with ID:" + artifact + " found."); + return null; + } + + AssertionStore as = (AssertionStore) assertionStoreSerializer.deserialize(assertion.getBytes()); + //delete the timestamp entry +// String ts = as.getDatatime().toString(); +// redisTemplate.opsForSet().pop(ts); + + if(as == null){ + Logger.debug("No transaction information with ID:" + artifact + " found."); + return null; + } + return as; + + //Assertion requires an unique artifact +// if (result.size() != 1) { +// Logger.debug("No transaction information with ID:" + artifact + " found."); +// +// +// } +// +// return (AssertionStore) result.get(0); + } + + private void put(AssertionStore element, String key, Object value, int timeoutms) throws MOADatabaseException { + + element = prepareAssertion(element, key, value); + + int authDataTimeOut = authConfig.getTransactionTimeOut() * 1000; + + if(timeoutms != -1){ + authDataTimeOut = timeoutms; + } + redisTemplate.opsForValue().set(element.getArtifact(), new String(assertionStoreSerializer.serialize(element)),authDataTimeOut,TimeUnit.MILLISECONDS); + //MOASessionDBUtils.saveOrUpdate(element); + Logger.debug(value.getClass().getName() + " with ID: " + key + " is stored in Database"); + + } + +private AssertionStore prepareAssertion(AssertionStore element, String key, Object value) throws MOADatabaseException { + + if(element == null) + element = new AssertionStore(); + + element.setArtifact(key); + element.setType(value.getClass().getName()); + element.setDatatime(new Date()); + + if (!Serializable.class.isInstance(value)) { + Logger.warn("Transaction-Storage can only store objects which implements the 'Seralizable' interface"); + throw new MOADatabaseException("Transaction-Storage can only store objects which implements the 'Seralizable' interface", null); + } + + //serialize the Assertion for Database storage + byte[] data = SerializationUtils.serialize((Serializable) value); + element.setAssertion(data); + + long id = new Random().nextLong(); + element.setId(id); + + return element; + + } + +@Override +public Object getAssertionStore(String key) throws MOADatabaseException { + return searchInDatabase(key); +} + +@Override +public void putAssertionStore(Object element) throws MOADatabaseException { + // TODO Auto-generated method stub + AssertionStore as = (AssertionStore)element; + final int expTime = redisTemplate.getExpire(as.getArtifact(), TimeUnit.MILLISECONDS).intValue(); + //AssertionStore element = searchInDatabase(oldKey); + if (expTime < 0) { + Logger.info("No transaction-data with oldKey:" + as.getArtifact() + + " found. Process gets stopped."); + throw new MOADatabaseException("No transaction-data with oldKey:" + as.getArtifact() + + " found. Process gets stopped."); + + } + redisTemplate.opsForValue().set(as.getArtifact(), new String(assertionStoreSerializer.serialize(element)),expTime,TimeUnit.MILLISECONDS); + +} + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAKeyValueConverter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAKeyValueConverter.java index 2c0a82708..f37ae0b0b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAKeyValueConverter.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ECDSAKeyValueConverter.java @@ -20,48 +20,15 @@ * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. ******************************************************************************/ -/* - * Copyright 2003 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - */ - package at.gv.egovernment.moa.id.util; -import iaik.security.ecc.ecdsa.ECDSAParameter; -import iaik.security.ecc.ecdsa.ECPublicKey; -import iaik.security.ecc.math.ecgroup.AffineCoordinate; -import iaik.security.ecc.math.ecgroup.Coordinate; -import iaik.security.ecc.math.ecgroup.CoordinateTypes; -import iaik.security.ecc.math.ecgroup.ECGroupFactory; -import iaik.security.ecc.math.ecgroup.ECPoint; -import iaik.security.ecc.math.ecgroup.EllipticCurve; -import iaik.security.ecc.math.field.Field; -import iaik.security.ecc.math.field.FieldElement; -import iaik.security.ecc.math.field.PrimeField; -import iaik.security.ecc.parameter.ECCParameterFactory; -import iaik.security.ecc.spec.ECCParameterSpec; - import java.math.BigInteger; import java.security.PublicKey; +import java.security.spec.ECField; +import java.security.spec.ECFieldF2m; +import java.security.spec.ECFieldFp; +import java.security.spec.ECPoint; import java.util.HashMap; import java.util.Iterator; import java.util.Vector; @@ -72,6 +39,15 @@ import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import at.gv.egovernment.moa.logging.Logger; +import iaik.security.ec.common.ECParameterSpec; +import iaik.security.ec.common.ECPublicKey; +import iaik.security.ec.common.ECStandardizedParameterFactory; +import iaik.security.ec.common.EllipticCurve; +import iaik.security.ec.math.field.Field; +import iaik.security.ec.math.field.FieldElement; +import iaik.security.ec.math.field.PrimeField; + public class ECDSAKeyValueConverter { @@ -94,15 +70,13 @@ public class ECDSAKeyValueConverter if (domainParams == null) throw new Exception("Domain parameters must not be implicit."); Element namedCurve = getChildElement(domainParams, ecdsaNS, "NamedCurve", 1); - ECCParameterSpec eccParameterSpec; + ECParameterSpec eccParameterSpec; if (namedCurve != null) { // URL curveNameURN = new URL(namedCurve.getAttributeNS(null, "URN")); String curveNameOID = namedCurve.getAttributeNS(null, "URN").substring(8); - ECCParameterFactory eccParamFactory = ECCParameterFactory.getInstance(); - // eccParameterSpec = eccParamFactory.getParameterByOID(curveNameURN.getPath().substring(4)); - eccParameterSpec = eccParamFactory.getParameterByOID(curveNameOID); + eccParameterSpec = ECStandardizedParameterFactory.getParametersByOID(curveNameOID); } else { @@ -167,14 +141,21 @@ public class ECDSAKeyValueConverter String cofactorStr = getChildElementText(basePointParams, ecdsaNS, "Cofactor", 1); BigInteger cofactor = (cofactorStr != null) ? new BigInteger(cofactorStr, 10) : null; + BigInteger a = new BigInteger(aStr, 10); + BigInteger b = new BigInteger(bStr, 10); + BigInteger basePointX = new BigInteger(basePointXStr, 10); + BigInteger basePointY = new BigInteger(basePointYStr, 10); + if (fieldParamsType == FIELD_TYPE_PRIME) - { - BigInteger a = new BigInteger(aStr, 10); - BigInteger b = new BigInteger(bStr, 10); - BigInteger basePointX = new BigInteger(basePointXStr, 10); - BigInteger basePointY = new BigInteger(basePointYStr, 10); - eccParameterSpec = new ECCParameterSpec(p, cofactor, order, seed, null, a, b, basePointX, - basePointY, null); + { + ECField javaECField = new ECFieldFp(p); + java.security.spec.EllipticCurve curve = + new java.security.spec.EllipticCurve(javaECField, a, b, seed.toByteArray()); + java.security.spec.ECPoint javaECbasePoint = + new java.security.spec.ECPoint(basePointX, basePointY); + java.security.spec.ECParameterSpec javaECSpec = + new java.security.spec.ECParameterSpec(curve, javaECbasePoint, order, cofactor.intValue()); + eccParameterSpec = ECParameterSpec.getParameterSpec(javaECSpec); } else { @@ -193,9 +174,19 @@ public class ECDSAKeyValueConverter irreducible[k1/32] += 1 << k1 % 32; irreducible[0] += 1; } - eccParameterSpec = new ECCParameterSpec(irreducible, cofactor, order, octetString2IntArray(aStr), - octetString2IntArray(bStr), octetString2IntArray(basePointXStr), - octetString2IntArray(basePointYStr), null); + + ECField javaECField = new ECFieldF2m(m, irreducible); + java.security.spec.EllipticCurve curve = + new java.security.spec.EllipticCurve(javaECField, a, b, seed.toByteArray()); + java.security.spec.ECPoint javaECbasePoint = + new java.security.spec.ECPoint(basePointX, basePointY); + java.security.spec.ECParameterSpec javaECSpec = + new java.security.spec.ECParameterSpec(curve, javaECbasePoint, order, cofactor.intValue()); + eccParameterSpec = ECParameterSpec.getParameterSpec(javaECSpec); + +// eccParameterSpec = new ECCParameterSpec(irreducible, cofactor, order, octetString2IntArray(aStr), +// octetString2IntArray(bStr), octetString2IntArray(basePointXStr), +// octetString2IntArray(basePointYStr), null); } } @@ -206,10 +197,14 @@ public class ECDSAKeyValueConverter Element publicKeyYElem = getChildElement(publicKeyElem, ecdsaNS, "Y", 1); String publicKeyYStr = publicKeyYElem.getAttributeNS(null, "Value"); - ECDSAParameter ecdsaParams = new ECDSAParameter(eccParameterSpec, CoordinateTypes.PROJECTIVE_COORDINATES); - ECGroupFactory ecGroupFactory = ECGroupFactory.getInstance(); - EllipticCurve eCurve = ecGroupFactory.getCurve(eccParameterSpec.getA(), - eccParameterSpec.getB(), eccParameterSpec.getR(), CoordinateTypes.PROJECTIVE_COORDINATES); + //ECParameterSpec ecdsaParams = new ECParameterSpec(eccParameterSpec, CoordinateTypes.PROJECTIVE_COORDINATES); + //ECGroupFactory ecGroupFactory = ECGroupFactory.getInstance(); + + EllipticCurve eCurve = eccParameterSpec.getCurve(); + +// EllipticCurve eCurve = ecGroupFactory.getCurve(eccParameterSpec.getA(), +// eccParameterSpec.getB(), eccParameterSpec.getR(), CoordinateTypes.PROJECTIVE_COORDINATES); + Field field = eCurve.getField(); // Detect type of public key field elements @@ -239,10 +234,19 @@ public class ECDSAKeyValueConverter } // ProjectiveCoordinate publicKeyPointCoordinate = new ProjectiveCoordinate(publicKeyPointX, // publicKeyPointY, field.getONEelement()); - Coordinate publicKeyPointCoordinate = new AffineCoordinate(publicKeyPointX, - publicKeyPointY).toProjective(); - ECPoint publicKeyPoint = eCurve.newPoint(publicKeyPointCoordinate); - ECPublicKey publicKey = new ECPublicKey(ecdsaParams, publicKeyPoint); +// Coordinate publicKeyPointCoordinate = new AffineCoordinate(publicKeyPointX, +// publicKeyPointY).toProjective(); + + ECPoint publicKeyPointECPoint = new ECPoint(publicKeyPointX.toBigInteger(), + publicKeyPointY.toBigInteger()); + + if (!eCurve.containsPoint(publicKeyPointECPoint)) { + Logger.error("IDL ECC parameter extraction FAILED! Public-Key ECPoint is not on the curve!"); + throw new Exception("IDL ECC parameter extraction FAILED! Public-Key ECPoint is not on the curve!"); + + } + + ECPublicKey publicKey = new ECPublicKey(eccParameterSpec, publicKeyPointECPoint); return publicKey; } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/SSLUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/SSLUtils.java index f0cec1d61..caf7f570f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/SSLUtils.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/SSLUtils.java @@ -46,9 +46,6 @@ package at.gv.egovernment.moa.id.util; -import iaik.pki.PKIException; -import iaik.security.provider.IAIK; - import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.IOException; @@ -57,7 +54,6 @@ import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; import java.security.GeneralSecurityException; -import java.security.Security; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLSocketFactory; @@ -71,6 +67,7 @@ import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.utils.ssl.SSLConfigurationException; import at.gv.egovernment.moa.id.config.ConnectionParameter; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import iaik.pki.PKIException; /** @@ -86,7 +83,7 @@ public class SSLUtils { public static void initialize() { // JSSE Abhängigkeit //Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); - Security.addProvider(new IAIK()); + //Security.addProvider(new IAIK()); //System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol"); @@ -126,8 +123,7 @@ public class SSLUtils { //INFO: MOA-ID 2.x always use defaultChainingMode try { - SSLSocketFactory ssf = - at.gv.egovernment.moa.id.commons.utils.ssl.SSLUtils.getSSLSocketFactory( + SSLSocketFactory ssf = at.gv.egovernment.moa.id.commons.utils.ssl.SSLUtils.getSSLSocketFactory( connParam.getUrl(), conf.getCertstoreDirectory(), trustStoreURL, diff --git a/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml b/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml index 11d92cea3..ba8c47304 100644 --- a/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml +++ b/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml @@ -4,10 +4,17 @@ 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:p="http://www.springframework.org/schema/p" + xmlns:task="http://www.springframework.org/schema/task" 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/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd + http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> + + <task:annotation-driven executor="MOA-ID-Auth_TaskExecutor" scheduler="MOA-ID-Auth_Scheduler"/> + <task:executor id="MOA-ID-Auth_TaskExecutor" pool-size="5"/> + <task:scheduler id="MOA-ID-Auth_Scheduler" pool-size="10"/> <bean id="processEngine" class="at.gv.egovernment.moa.id.process.ProcessEngineImpl"> <property name="transitionConditionExpressionEvaluator"> @@ -35,8 +42,7 @@ <bean id="MOAID_SSOManager" class="at.gv.egovernment.moa.id.moduls.SSOManager"/> - <bean id="TransactionStorage" - class="at.gv.egovernment.moa.id.storage.DBTransactionStorage"/> + <bean id="AuthenticationSessionStoreage" class="at.gv.egovernment.moa.id.storage.DBAuthenticationSessionStoreage"/> @@ -47,14 +53,20 @@ <bean id="ProcessInstanceStoreage" class="at.gv.egovernment.moa.id.process.dao.ProcessInstanceStoreDAOImpl"/> - <bean id="StatisticLogger" - class="at.gv.egovernment.moa.id.advancedlogging.StatisticLogger"/> - <bean id="MOAReversionLogger" class="at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger"/> <bean id="AuthenticationSessionCleaner" - class="at.gv.egovernment.moa.id.auth.AuthenticationSessionCleaner"/> + class="at.gv.egovernment.moa.id.auth.AuthenticationSessionCleaner"/> + + <bean id="MOAGarbageCollector" + class="at.gv.egovernment.moa.id.auth.MOAGarbageCollector"/> + +<!-- <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> + <property name="corePoolSize" value="5" /> + <property name="maxPoolSize" value="10" /> + <property name="queueCapacity" value="25" /> + </bean> --> <!-- Authentication Process Tasks --> <bean id="GenerateBKUSelectionFrameTask" @@ -79,6 +91,18 @@ <bean id="EvaluateSSOConsentsTaskImpl" class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.EvaluateSSOConsentsTaskImpl" - scope="prototype"/> + scope="prototype"/> -</beans>
\ No newline at end of file + <beans profile="advancedLogOn"> + <bean id="StatisticLogger" + class="at.gv.egovernment.moa.id.advancedlogging.StatisticLogger"/> + </beans> + + <beans profile="advancedLogOff"> + <bean id="StatisticLogger" + class="at.gv.egovernment.moa.id.advancedlogging.DummyStatisticLogger"/> + </beans> + +</beans> + + diff --git a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties index 400b0bc25..36f1392d5 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties @@ -113,9 +113,9 @@ service.00=Fehler beim Aufruf des Web Service: {0} service.01=Fehler beim Aufruf des Web Service: kein Endpoint
service.02=Fehler beim Aufruf des Web Service, Status {0}: {1}
service.03=Fehler beim Aufruf des SPSS-API: {0}
-service.04=Das Online-Vollmachten Service ist unter {0} nicht erreichbar.
+service.04=Das Online-Vollmachten Service ist unter {0} nicht erreichbar. Ursache:{1}
service.05=Fehler beim Anfragen des Online-Vollmachen Service: {0} / {1}
-service.06=Allgemeiner Fehler beim Anfragen des Online-Vollmachten Service
+service.06=Allgemeiner Fehler beim Anfragen des Online-Vollmachten Service. Ursache:{0}
service.07=Der SZR-Gateway ist unter {0} nicht erreichbar.
service.08=Die Eintragung der ausländischen Person am SZR-Gateway ist fehlgeschlagen.
service.09=Der SZR-Gateway Client konnte nicht initialisiert werden.
@@ -258,7 +258,7 @@ stork.29=Fehler bei der Generierung von STORK-Attribut (eIdentifier/eLPIdentifie eIDAS.00=eIDAS Engine initialization FAILED. Reason:{0}
eIDAS.01=Received eIDAS AuthnRequest is not valid. Reason:{0}
-eIDAS.02=Generate eIDAS AuthnRequest FAILED. Reason:{0}
+eIDAS.02=Generation of eIDAS AuthnRequest FAILED. Reason:{0}
eIDAS.03=Can not connect to eIDAS Node. Reason:No CitizenCountry selected.
eIDAS.04=Can not connect to eIDAS Node. Reason:{0} is not a valid CitizenCountry.
eIDAS.05=Can not generate eIDAS metadata. Reason:{0}
@@ -267,7 +267,10 @@ eIDAS.07=Missing eIDAS-Attribute:{0} eIDAS.08=No valid eIDAs-Node configuration for enityID:{0}
eIDAS.09=Received eIDAS Response is not valid. Reason:{0}
eIDAS.10=Internal server error. Reason:{0}
-eIDAS.11=Received eIDAS Error-Response. Reason:{0}
+eIDAS.11=Received eIDAS Error-Response. Reason:{0}
+eIDAS.12=Received eIDAS AuthnRequest is not valid. Reason:{0}
+eIDAS.13=Generation of eIDAS Response FAILED. Reason:{0}
+eIDAS.14=eIDAS Response validation FAILED: LevelOfAssurance {0} is to low.
pvp2.01=Fehler beim kodieren der PVP2 Antwort
pvp2.02=Ungueltiges Datumsformat
diff --git a/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties index bfaf5ffb1..e72a28046 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties @@ -225,6 +225,9 @@ eIDAS.08=1304 eIDAS.09=1301 eIDAS.10=9199 eIDAS.11=1302 +eIDAS.12=1305 +eIDAS.13=1307 +eIDAS.14=1301 pvp2.01=6100 pvp2.06=6100 diff --git a/id/server/idserverlib/src/main/resources/session.common.beans.xml b/id/server/idserverlib/src/main/resources/session.common.beans.xml new file mode 100644 index 000000000..defa47ec0 --- /dev/null +++ b/id/server/idserverlib/src/main/resources/session.common.beans.xml @@ -0,0 +1,74 @@ +<?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:p="http://www.springframework.org/schema/p" + 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:property-placeholder location="${moa.id.configuration}"/> + <context:annotation-config/> + + <bean id="sessionDataSource" class="org.apache.commons.dbcp2.BasicDataSource" lazy-init="true" destroy-method="close"> + <aop:scoped-proxy/> + <property name="driverClassName" value="${moasession.hibernate.connection.driver_class}" /> + <property name="url" value="${moasession.hibernate.connection.url}"/> + <property name="username" value="${moasession.hibernate.connection.username}" /> + <property name="password" value="${moasession.hibernate.connection.password}" /> + + <property name="connectionProperties" value="${moasession.dbcp.connectionProperties}" /> + <property name="initialSize" value="${moasession.dbcp.initialSize}" /> + <property name="maxTotal" value="${moasession.dbcp.maxActive}" /> + <property name="maxIdle" value="${moasession.dbcp.maxIdle}" /> + <property name="minIdle" value="${moasession.dbcp.minIdle}" /> + <!-- property name="maxWait" value="${moasession.dbcp.maxWaitMillis}" / --> + <property name="testOnBorrow" value="${moasession.dbcp.testOnBorrow}" /> + <property name="testOnReturn" value="${moasession.dbcp.testOnReturn}" /> + <property name="testWhileIdle" value="${moasession.dbcp.testWhileIdle}" /> + <property name="validationQuery" value="${moasession.dbcp.validationQuery}" /> + </bean> + + <bean id="sessionSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> + <property name="dataSource" ref="sessionDataSource"/> + <property name="packagesToScan" value="at.gv.egovernment.moa.id.commons.db.dao.session" /> + <property name="hibernateProperties"> + <props> + <prop key="hibernate.dialect">${moasession.hibernate.dialect}</prop> + <prop key="hibernate.show_sql">${moasession.hibernate.show_sql}</prop> + <prop key="hibernate.hbm2ddl.auto">${moasession.hibernate.hbm2ddl.auto}</prop> + <prop key="current_session_context_class">${moasession.hibernate.current_session_context_class}</prop> + <prop key="hibernate.transaction.flush_before_completion">${moasession.hibernate.transaction.flush_before_completion}</prop> + <prop key="hibernate.transaction.auto_close_session">${moasession.hibernate.transaction.auto_close_session}</prop> + </props> + </property> + </bean> + + <!-- MYSQL Conector --> + <tx:annotation-driven transaction-manager="sessionTransactionManager"/> + + <bean id="sessionJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> + <property name="showSql" value="${moasession.hibernate.show_sql}" /> + <property name="generateDdl" value="${moasession.jpaVendorAdapter.generateDdl}" /> + <property name="databasePlatform" value="${moasession.hibernate.dialect}" /> + </bean> + + <bean name="session" id="session" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" depends-on="sessionDataSource"> + <property name="dataSource" ref="sessionDataSource" /> + <property name="jpaVendorAdapter" ref="sessionJpaVendorAdapter" /> + <property name="packagesToScan" value="at.gv.egovernment.moa.id.commons.db.dao.session" /> + <property name="persistenceUnitName" value="session" /> + </bean> + + <bean name="sessionTransactionManager" id="sessionTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> + <property name="entityManagerFactory" ref="session" /> + </bean> + + <bean id="moaSessionDBUtils" class="at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils"> + </bean> + +</beans>
\ No newline at end of file diff --git a/id/server/idserverlib/src/main/resources/session.db.beans.xml b/id/server/idserverlib/src/main/resources/session.db.beans.xml new file mode 100644 index 000000000..5ed390ffe --- /dev/null +++ b/id/server/idserverlib/src/main/resources/session.db.beans.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans profile="dbBackend" + 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:p="http://www.springframework.org/schema/p" + 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:property-placeholder location="${moa.id.configuration}"/> + + <bean id="TransactionStorage" + class="at.gv.egovernment.moa.id.storage.DBTransactionStorage" + /> + +</beans>
\ No newline at end of file diff --git a/id/server/idserverlib/src/main/resources/session.redis.beans.xml b/id/server/idserverlib/src/main/resources/session.redis.beans.xml new file mode 100644 index 000000000..feda9b273 --- /dev/null +++ b/id/server/idserverlib/src/main/resources/session.redis.beans.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans profile="redisBackend" + 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:p="http://www.springframework.org/schema/p" + 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:property-placeholder location="${moa.id.configuration}"/> + + <bean id="TransactionStorage" + class="at.gv.egovernment.moa.id.storage.RedisTransactionStorage"/> + + <!-- Redis Beans --> + <bean id="jedisConnFactory" + class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" + p:use-pool="${redis.use-pool}" + p:host-name="${redis.host-name}" + p:port="${redis.port}"/> + + <bean id="RedisStringSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" /> + <bean id="assertionStoreSerializer" class="org.springframework.data.redis.serializer.JacksonJsonRedisSerializer"> + <constructor-arg type="java.lang.Class" value="at.gv.egovernment.moa.id.commons.db.dao.session.AssertionStore"/> + </bean> + + <bean id="redisTemplate" + class="org.springframework.data.redis.core.RedisTemplate" + p:connection-factory-ref="jedisConnFactory" + p:value-serializer-ref="RedisStringSerializer" + p:key-serializer-ref="RedisStringSerializer"/> + +</beans>
\ No newline at end of file diff --git a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/module/test/TestRequestImpl.java b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/module/test/TestRequestImpl.java index 66dffe311..0b5128c8b 100644 --- a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/module/test/TestRequestImpl.java +++ b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/module/test/TestRequestImpl.java @@ -24,6 +24,8 @@ package at.gv.egovernment.moa.id.module.test; import java.util.Collection; +import org.opensaml.saml2.metadata.provider.MetadataProvider; + 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.exceptions.SessionDataStorageException; @@ -254,7 +256,7 @@ public class TestRequestImpl implements IRequest { * @see at.gv.egovernment.moa.id.moduls.IRequest#getRequestedAttributes() */ @Override - public Collection<String> getRequestedAttributes() { + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider) { // TODO Auto-generated method stub return null; } diff --git a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/spring/test/DummyTransactionStorage.java b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/spring/test/DummyTransactionStorage.java new file mode 100644 index 000000000..ab08c0f5c --- /dev/null +++ b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/spring/test/DummyTransactionStorage.java @@ -0,0 +1,147 @@ +package at.gv.egovernment.moa.id.process.spring.test; + +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +import javax.sql.DataSource; + +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.storage.ITransactionStorage; +import at.gv.egovernment.moa.logging.Logger; + +/** + * Dummy DataSource implementation for convenience in test cases where a + * database connection will never actually be acquired. + * + * @see DataSource + * @author Chris Beams + */ +public class DummyTransactionStorage implements ITransactionStorage { + + public class DummyDBEntry{ + public DummyDBEntry(String key, Object value){ + this.obj =value; + this.key = key; + } + public String getKey() { + return key; + } + public void setKey(String key) { + this.key = key; + } + public Object getObj() { + return obj; + } + public void setObj(Object obj) { + this.obj = obj; + } + private String key; + private Object obj; + } + + private ArrayList<DummyDBEntry> ds = new ArrayList<DummyDBEntry>(); + + + + @Override + public boolean containsKey(String key) { + // TODO Auto-generated method stub + Iterator<DummyDBEntry> it = ds.iterator(); + while(it.hasNext()){ + DummyDBEntry t = it.next(); + if(t.getKey().equals(key)) + return true; + } + return false; + } + + @Override + public void put(String key, Object value, int timeout_ms) + throws MOADatabaseException { + // TODO Auto-generated method stub + this.remove(key); + this.ds.add(new DummyDBEntry(key, value)); + + } + + @Override + public Object get(String key) throws MOADatabaseException { + // TODO Auto-generated method stub + Iterator<DummyDBEntry> it = ds.iterator(); + while(it.hasNext()){ + DummyDBEntry t = it.next(); + if(t.getKey().equals(key)) + return t; + } + return null; + } + + @Override + public <T> T get(String key, Class<T> clazz) throws MOADatabaseException { + + DummyDBEntry o = (DummyDBEntry) get(key); + if(o == null) + return null; + try { + @SuppressWarnings("unchecked") + T test = (T) (clazz.cast(o.getObj())); + return test; + + } catch (Exception e) { + Logger.warn("Sessioninformation Cast-Exception by using Artifact=" + key); + throw new MOADatabaseException("Sessioninformation Cast-Exception"); + + } + } + + @Override + public <T> T get(String key, Class<T> clazz, long dataTimeOut) + throws MOADatabaseException, AuthenticationException { + // TODO Auto-generated method stub + return get(key,clazz); + } + + @Override + public void changeKey(String oldKey, String newKey, Object value) + throws MOADatabaseException { + this.remove(oldKey); + this.put(newKey, value, -1); + + } + + @Override + public void remove(String key) { + Iterator<DummyDBEntry> it = ds.iterator(); + while(it.hasNext()){ + DummyDBEntry t = it.next(); + if(t.getKey().equals(key)){ + this.ds.remove(t); + return; + } + } + + } + + @Override + public List<String> clean(Date now, long dataTimeOut) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object getAssertionStore(String key) throws MOADatabaseException { + // TODO Auto-generated method stub + return null; + } + + @Override + public void putAssertionStore(Object element) throws MOADatabaseException { + // TODO Auto-generated method stub + + } + + +}
\ No newline at end of file diff --git a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/spring/test/SpringExpressionAwareProcessEngineTest.java b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/spring/test/SpringExpressionAwareProcessEngineTest.java index 2cb2a3278..b308e2fa8 100644 --- a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/spring/test/SpringExpressionAwareProcessEngineTest.java +++ b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/spring/test/SpringExpressionAwareProcessEngineTest.java @@ -78,7 +78,7 @@ public class SpringExpressionAwareProcessEngineTest { config.addProperties(props); //config.addAnnotatedClass(ProcessInstanceStore.class); config.addAnnotatedClass(AssertionStore.class); - MOASessionDBUtils.initHibernate(config, props); + //MOASessionDBUtils.initHibernate(config, props); } catch (Exception e) { e.printStackTrace(); } diff --git a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/test/ProcessEngineTest.java b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/test/ProcessEngineTest.java index a7e351e25..197627a66 100644 --- a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/test/ProcessEngineTest.java +++ b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/test/ProcessEngineTest.java @@ -73,7 +73,7 @@ public class ProcessEngineTest { config.addProperties(props); //config.addAnnotatedClass(ProcessInstanceStore.class); config.addAnnotatedClass(AssertionStore.class); - MOASessionDBUtils.initHibernate(config, props); + //MOASessionDBUtils.initHibernate(config, props); } catch (Exception e) { e.printStackTrace(); } diff --git a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/storage/test/DBTransactionStorageTest.java b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/storage/test/DBTransactionStorageTest.java new file mode 100644 index 000000000..4b7f61ef5 --- /dev/null +++ b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/storage/test/DBTransactionStorageTest.java @@ -0,0 +1,122 @@ +package at.gv.egovernment.moa.id.storage.test; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.FileSystemXmlApplicationContext; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.storage.DBTransactionStorage; +import at.gv.egovernment.moa.id.storage.ITransactionStorage; +import at.gv.egovernment.moa.util.Constants; +import at.gv.util.DOMUtils; + +public class DBTransactionStorageTest { + + public static void main (String[] args) throws SAXException, IOException, ParserConfigurationException, MOADatabaseException{ + DBTransactionStorageTest t = new DBTransactionStorageTest(); + t.test(); + } + + @Autowired + DBTransactionStorage rts; + + public DBTransactionStorageTest(){ + + } + + + public void test() throws SAXException, IOException, ParserConfigurationException, MOADatabaseException{ + + + ApplicationContext context = new FileSystemXmlApplicationContext("src/test/java/testBeans.xml"); + + + String requestString = + "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + + "<samlp:Request xmlns:samlp=\"urn:oasis:names:tc:SAML:1.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" RequestID=\"123456\" MajorVersion=\"1\" MinorVersion=\"0\" IssueInstant=\"2003-02-13T13:59:00\">" + + "<samlp:AssertionArtifact>WRONGARTIFACT</samlp:AssertionArtifact>" + + "</samlp:Request>"; + Element request = DOMUtils.parseDocument(requestString, false, Constants.ALL_SCHEMA_LOCATIONS, null).getDocumentElement(); + + ITransactionStorage rts = (ITransactionStorage) context.getBean("DBTransactionStorage"); + //GenericToStringSerializer redisStringSerializer = (GenericToStringSerializer) context.getBean("valueObjectSerializer"); + + // rts.getTemplate().setValueSerializer(new GenericToStringSerializer<Object>(Object.class)); + // rts.getTemplate().setHashValueSerializer(new GenericToStringSerializer<Object>(Object.class)); + + int cnt = 10; + int averageCnt = 10; + long putTime = 0, getTime = 0, changeTime = 0, removeTime = 0; + long total = 0; + for(int a=0;a<averageCnt;a++){ + long totalPerRound = 0; + + System.out.println("Starting MySql store operation."); + long start = System.currentTimeMillis(); + for(int i=0; i<cnt;i++) + rts.put("test"+i, request,-1); + long end = System.currentTimeMillis(); + putTime += end-start; + System.out.println("MySql store operation done in "+(end-start)+" ms."); + totalPerRound+=(end-start); + + Element test; + System.out.println("Starting MySql get operation."); + start = System.currentTimeMillis(); + for(int i=0; i<cnt;i++) + test = (Element)rts.get("test"+i); + end = System.currentTimeMillis(); + getTime += end-start; + System.out.println("MySql get operation done in "+(end-start)+" ms."); + totalPerRound+=(end-start); + //Element test = (Element)rts.get("test0"); + //System.out.println("Read Element from Redis Store: "+test.getTextContent()); + + String requestString2 = + "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + + "<samlp:Request xmlns:samlp=\"urn:oasis:names:tc:SAML:1.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" RequestID=\"test_new\" MajorVersion=\"1\" MinorVersion=\"0\" IssueInstant=\"2003-02-13T13:59:00\">" + + "<samlp:AssertionArtifact>WRONGARTIFACT</samlp:AssertionArtifact>" + + "</samlp:Request>"; + Element request2 = DOMUtils.parseDocument(requestString2, false, Constants.ALL_SCHEMA_LOCATIONS, null).getDocumentElement(); + + System.out.println("Starting MySql change operation."); + start = System.currentTimeMillis(); + for(int i=0; i<cnt;i++) + rts.changeKey("test"+i, "test_new"+i, request2); + end = System.currentTimeMillis(); + changeTime += end-start; + System.out.println("MySql change operation done in "+(end-start)+" ms."); + totalPerRound+=(end-start); + + + + System.out.println("Starting MySql remove operation."); + start = System.currentTimeMillis(); + for(int i=0; i<cnt;i++) + rts.remove("test_new"+i); + end = System.currentTimeMillis(); + removeTime += end-start; + System.out.println("MySql remove operation done in "+(end-start)+" ms."); + totalPerRound+=(end-start); + total+=totalPerRound; + + System.out.println("Redis Total Time in this round: "+totalPerRound+" ms."); + System.out.println("______________________________________________________"); + } + System.out.println("______________________________________________________"); + System.out.println("Redis average get time over " + averageCnt +" rounds: "+getTime/averageCnt+" ms."); + System.out.println("Redis average put time over " + averageCnt +" rounds: "+putTime/averageCnt+" ms."); + System.out.println("Redis average change time over " + averageCnt +" rounds: "+changeTime/averageCnt+" ms."); + System.out.println("Redis average remove time over " + averageCnt +" rounds: "+removeTime/averageCnt+" ms."); + System.out.println("Redis average total time over " + averageCnt +" rounds: "+total/averageCnt+" ms."); + ((ConfigurableApplicationContext)context).close(); + } + +} diff --git a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/storage/test/RedisTransactionMultiThreadTest.java b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/storage/test/RedisTransactionMultiThreadTest.java new file mode 100644 index 000000000..60b55f497 --- /dev/null +++ b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/storage/test/RedisTransactionMultiThreadTest.java @@ -0,0 +1,130 @@ +package at.gv.egovernment.moa.id.storage.test; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.FileSystemXmlApplicationContext; +import org.springframework.core.task.TaskExecutor; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.storage.RedisTransactionStorage; +import at.gv.egovernment.moa.util.Constants; +import at.gv.util.DOMUtils; + +public class RedisTransactionMultiThreadTest { + + private ApplicationContext context; + + public RedisTransactionMultiThreadTest() throws SAXException, IOException, ParserConfigurationException, MOADatabaseException{ + this.context = new FileSystemXmlApplicationContext("src/test/java/testBeans.xml"); + TaskExecutor te = (TaskExecutor) context.getBean("taskExecutor"); + + for(int i=0;i<50;i++){ + te.execute(new RedisTask("Task"+i)); + } + + + } + + public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException, MOADatabaseException{ + + RedisTransactionMultiThreadTest t = new RedisTransactionMultiThreadTest(); + System.out.println("End"); + +// String requestString = +// "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + +// "<samlp:Request xmlns:samlp=\"urn:oasis:names:tc:SAML:1.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" RequestID=\"123456\" MajorVersion=\"1\" MinorVersion=\"0\" IssueInstant=\"2003-02-13T13:59:00\">" + +// "<samlp:AssertionArtifact>WRONGARTIFACT</samlp:AssertionArtifact>" + +// "</samlp:Request>"; +// Element request = DOMUtils.parseDocument(requestString, false, Constants.ALL_SCHEMA_LOCATIONS, null).getDocumentElement(); +// +// +// +// +// RedisTransactionStorage rts = (RedisTransactionStorage) context.getBean("TransactionStorage"); +// //GenericToStringSerializer redisStringSerializer = (GenericToStringSerializer) context.getBean("valueObjectSerializer"); +// +//// rts.getTemplate().setValueSerializer(new GenericToStringSerializer<Object>(Object.class)); +//// rts.getTemplate().setHashValueSerializer(new GenericToStringSerializer<Object>(Object.class)); +// +// +// rts.put("test", request,-1); +// System.out.println("Redis store operation done!"); +// +// Element test = (Element)rts.get("test"); +// System.out.println("Read Element from Redis Store: "+test.getTextContent()); +// +// String requestString2 = +// "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + +// "<samlp:Request xmlns:samlp=\"urn:oasis:names:tc:SAML:1.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" RequestID=\"test_new\" MajorVersion=\"1\" MinorVersion=\"0\" IssueInstant=\"2003-02-13T13:59:00\">" + +// "<samlp:AssertionArtifact>WRONGARTIFACT</samlp:AssertionArtifact>" + +// "</samlp:Request>"; +// Element request2 = DOMUtils.parseDocument(requestString2, false, Constants.ALL_SCHEMA_LOCATIONS, null).getDocumentElement(); +// +// +// rts.changeKey("test", "test_new", request2); +// +// rts.remove("test"); +// rts.remove("test_new"); +// +// ((ConfigurableApplicationContext)context).close(); + } + + private class RedisTask implements Runnable { + + private String message; + + public RedisTask(String message) throws SAXException, IOException, ParserConfigurationException, MOADatabaseException { + + this.message = message; + + + + } + + public void run() { + String requestString = + "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + + "<samlp:Request xmlns:samlp=\"urn:oasis:names:tc:SAML:1.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" RequestID=\"123456\" MajorVersion=\"1\" MinorVersion=\"0\" IssueInstant=\"2003-02-13T13:59:00\">" + + "<samlp:AssertionArtifact>WRONGARTIFACT</samlp:AssertionArtifact>" + + "</samlp:Request>"; + + Element request = null; + try { + request = DOMUtils.parseDocument(requestString, false, Constants.ALL_SCHEMA_LOCATIONS, null).getDocumentElement(); + } catch (SAXException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return; + } catch (ParserConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return; + } + + RedisTransactionStorage rts = (RedisTransactionStorage) context.getBean("RedisTransactionStorage"); + + try { + rts.put(message, request,-1); + rts.changeKey(message, message+"n", request); + } catch (MOADatabaseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return; + } + System.out.println("Done with task "+message); + } + + } + +} diff --git a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/storage/test/RedisTransactionStorageTest.java b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/storage/test/RedisTransactionStorageTest.java new file mode 100644 index 000000000..e957ffe05 --- /dev/null +++ b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/storage/test/RedisTransactionStorageTest.java @@ -0,0 +1,116 @@ +package at.gv.egovernment.moa.id.storage.test; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.FileSystemXmlApplicationContext; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.storage.DBTransactionStorage; +import at.gv.egovernment.moa.id.storage.RedisTransactionStorage; +import at.gv.egovernment.moa.util.Constants; +import at.gv.util.DOMUtils; + +public class RedisTransactionStorageTest { + + + public RedisTransactionStorageTest(){ + + } + + public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException, MOADatabaseException{ + + + ApplicationContext context = new FileSystemXmlApplicationContext("src/test/java/testBeans.xml"); + + + String requestString = + "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + + "<samlp:Request xmlns:samlp=\"urn:oasis:names:tc:SAML:1.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" RequestID=\"123456\" MajorVersion=\"1\" MinorVersion=\"0\" IssueInstant=\"2003-02-13T13:59:00\">" + + "<samlp:AssertionArtifact>WRONGARTIFACT</samlp:AssertionArtifact>" + + "</samlp:Request>"; + Element request = DOMUtils.parseDocument(requestString, false, Constants.ALL_SCHEMA_LOCATIONS, null).getDocumentElement(); + + RedisTransactionStorage rts = (RedisTransactionStorage) context.getBean("RedisTransactionStorage"); + //GenericToStringSerializer redisStringSerializer = (GenericToStringSerializer) context.getBean("valueObjectSerializer"); + + // rts.getTemplate().setValueSerializer(new GenericToStringSerializer<Object>(Object.class)); + // rts.getTemplate().setHashValueSerializer(new GenericToStringSerializer<Object>(Object.class)); + + int cnt = 100; + int averageCnt = 10; + long putTime = 0, getTime = 0, changeTime = 0, removeTime = 0; + long total = 0; + for(int a=0;a<averageCnt;a++){ + long totalPerRound = 0; + + System.out.println("Starting Redis store operation."); + long start = System.currentTimeMillis(); + for(int i=0; i<cnt;i++) + rts.put("test"+i, request,-1); + long end = System.currentTimeMillis(); + putTime += end-start; + System.out.println("Redis store operation done in "+(end-start)+" ms."); + totalPerRound+=(end-start); + + Element test; + System.out.println("Starting Redis get operation."); + start = System.currentTimeMillis(); + for(int i=0; i<cnt;i++) + test = (Element)rts.get("test"+i); + end = System.currentTimeMillis(); + getTime += end-start; + System.out.println("Redis get operation done in "+(end-start)+" ms."); + totalPerRound+=(end-start); + //Element test = (Element)rts.get("test0"); + //System.out.println("Read Element from Redis Store: "+test.getTextContent()); + + String requestString2 = + "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + + "<samlp:Request xmlns:samlp=\"urn:oasis:names:tc:SAML:1.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" RequestID=\"test_new\" MajorVersion=\"1\" MinorVersion=\"0\" IssueInstant=\"2003-02-13T13:59:00\">" + + "<samlp:AssertionArtifact>WRONGARTIFACT</samlp:AssertionArtifact>" + + "</samlp:Request>"; + Element request2 = DOMUtils.parseDocument(requestString2, false, Constants.ALL_SCHEMA_LOCATIONS, null).getDocumentElement(); + + System.out.println("Starting Redis change operation."); + start = System.currentTimeMillis(); + for(int i=0; i<cnt;i++) + rts.changeKey("test"+i, "test_new"+i, request2); + end = System.currentTimeMillis(); + changeTime += end-start; + System.out.println("Redis change operation done in "+(end-start)+" ms."); + totalPerRound+=(end-start); + + + + System.out.println("Starting Redis remove operation."); + start = System.currentTimeMillis(); + for(int i=0; i<cnt;i++) + rts.remove("test_new"+i); + end = System.currentTimeMillis(); + removeTime += end-start; + System.out.println("Redis remove operation done in "+(end-start)+" ms."); + totalPerRound+=(end-start); + total+=totalPerRound; + + System.out.println("Redis Total Time in this round: "+totalPerRound+" ms."); + System.out.println("______________________________________________________"); + } + System.out.println("______________________________________________________"); + System.out.println("Redis average get time over " + averageCnt +" rounds: "+getTime/averageCnt+" ms."); + System.out.println("Redis average put time over " + averageCnt +" rounds: "+putTime/averageCnt+" ms."); + System.out.println("Redis average change time over " + averageCnt +" rounds: "+changeTime/averageCnt+" ms."); + System.out.println("Redis average remove time over " + averageCnt +" rounds: "+removeTime/averageCnt+" ms."); + System.out.println("Redis average total time over " + averageCnt +" rounds: "+total/averageCnt+" ms."); + + ((ConfigurableApplicationContext)context).close(); + + + } + +} diff --git a/id/server/idserverlib/src/test/java/test/tlenz/simpletest.java b/id/server/idserverlib/src/test/java/test/tlenz/simpletest.java index 2c80b7ffd..05cd74ed2 100644 --- a/id/server/idserverlib/src/test/java/test/tlenz/simpletest.java +++ b/id/server/idserverlib/src/test/java/test/tlenz/simpletest.java @@ -1,23 +1,23 @@ package test.tlenz; -import java.io.File; import java.io.FileInputStream; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.net.URI; -import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.List; -import org.w3c.dom.Element; +import org.apache.commons.io.IOUtils; +import org.w3c.dom.NodeList; -import iaik.asn1.structures.Name; -import iaik.utils.RFC2253NameParser; -import iaik.utils.RFC2253NameParserException; -import at.gv.egovernment.moa.id.auth.data.IdentityLink; -import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser; -import at.gv.egovernment.moa.id.data.AuthenticationRole; -import at.gv.egovernment.moa.id.data.AuthenticationRoleFactory; -import at.gv.egovernment.moa.id.util.IdentityLinkReSigner; -import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.spss.api.SPSSFactory; +import at.gv.egovernment.moa.spss.api.SignatureVerificationService; +import at.gv.egovernment.moa.spss.api.common.Content; +import at.gv.egovernment.moa.spss.api.common.ContentBinary; +import at.gv.egovernment.moa.spss.api.common.ContentXML; +import at.gv.egovernment.moa.spss.api.common.InputData; +import at.gv.egovernment.moa.spss.api.common.SignerInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureInfo; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; /******************************************************************************* * Copyright 2014 Federal Chancellery Austria @@ -62,71 +62,130 @@ import at.gv.egovernment.moa.util.DOMUtils; public class simpletest { // public static void main(String[] args) { - - URI fileURI = null; - try { - fileURI = new URI("file:c:/moa3/tomcat8/conf/moa-id/moa-id.properties"); - File propertiesFile = new File(fileURI); + try { + FileInputStream sigDocFIS = null; + sigDocFIS = new FileInputStream("D:/idl_test/identity_link.xml"); - InputStream in = new FileInputStream(propertiesFile); - ObjectInputStream testOIS = new ObjectInputStream(in); + SPSSFactory spssFac = SPSSFactory.getInstance(); + SignatureVerificationService sigVerifyService = SignatureVerificationService.getInstance(); + Content sigDocContent = spssFac.createContent(sigDocFIS, null); + + + // Position der zu pruefenden Signatur + HashMap nSMap = new HashMap(); + nSMap.put("dsig", "http://www.w3.org/2000/09/xmldsig#"); + VerifySignatureLocation sigLocation = spssFac.createVerifySignatureLocation("//dsig:Signature", nSMap); + + // Pruefrequest zusammenstellen + VerifySignatureInfo sigInfo = spssFac.createVerifySignatureInfo(sigDocContent, sigLocation); + VerifyXMLSignatureRequest verifyRequest = spssFac.createVerifyXMLSignatureRequest( + null, // Verwende aktuelle Zeit als Pruefzeit + sigInfo, + null, // Keine Ergaenzungsobjekte + null, // Signaturmanifest-Pruefung soll nicht durchgefuehrt werden + true, // Hash-Inputdaten, d.h. tatsaechlich signierte Daten werden nicht zurueckgeliefert + "MOAIDBuergerkarteAuthentisierungsDaten"); + + + VerifyXMLSignatureResponse verifyResponse = null; + verifyResponse = sigVerifyService.verifyXMLSignature(verifyRequest); + + SignerInfo signerInfo = verifyResponse.getSignerInfo(); + String signerCertificateEncoded = null; + + List hashInputDatas = verifyResponse.getHashInputDatas(); + if (hashInputDatas != null && !hashInputDatas.isEmpty()) { + for (Object el : hashInputDatas) { + InputData inputData = (InputData) el; + switch (inputData.getContentType()) { + case Content.XML_CONTENT : + ContentXML contentXml = (ContentXML) inputData; + NodeList input_XML = contentXml.getXMLContent(); + + break; + case Content.BINARY_CONTENT : + ContentBinary contentBinary = (ContentBinary) inputData; + String input_Binary = IOUtils.toString(contentBinary.getBinaryContent()); + + } + } + } + + - Object test = testOIS.readObject(); + } catch (Exception e) { - } catch (Exception e1) { - e1.printStackTrace(); - } - - try { - fileURI = new URI("file:/c:/moa3/tomcat8/conf/moa-id/moa-id.properties"); - File propertiesFile = new File(fileURI); - } catch (Exception e1) { - e1.printStackTrace(); - } - - try { - fileURI = new URI("file://c:/moa3/tomcat8/conf/moa-id/moa-id.properties"); - File propertiesFile = new File(fileURI); - } catch (Exception e1) { - e1.printStackTrace(); - } - - try { - fileURI = new URI("file:///c:/moa3/tomcat8/conf/moa-id/moa-id.properties"); - File propertiesFile = new File(fileURI); - } catch (Exception e1) { - e1.printStackTrace(); } - try { - InputStream s = new FileInputStream("D:/idl_test/identity_link.xml"); - Element idlTemplate = DOMUtils.parseXmlValidating(s); - - //resign IDL - IdentityLinkReSigner identitylinkresigner = IdentityLinkReSigner.getInstance(); - Element resignedilAssertion = identitylinkresigner.resignIdentityLink(idlTemplate, "IDLSigning"); - IdentityLink identityLink = new IdentityLinkAssertionParser(resignedilAssertion).parseIdentityLink(); - - } catch (Exception e) { - System.out.println(e.getMessage()); - - } - String subjectName = "serialNumber=896929130327, givenName=OCSP, SN=Responder 03-1, CN=OCSP Responder 03-1, C=AT"; - try { - Name test = new RFC2253NameParser(subjectName).parse(); - - System.out.println(test.getRFC2253String()); - - } catch (RFC2253NameParserException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } +// URI fileURI = null; +// try { +// fileURI = new URI("file:c:/moa3/tomcat8/conf/moa-id/moa-id.properties"); +// File propertiesFile = new File(fileURI); +// +// InputStream in = new FileInputStream(propertiesFile); +// ObjectInputStream testOIS = new ObjectInputStream(in); +// +// Object test = testOIS.readObject(); +// +// +// } catch (Exception e1) { +// e1.printStackTrace(); +// } +// +// try { +// fileURI = new URI("file:/c:/moa3/tomcat8/conf/moa-id/moa-id.properties"); +// File propertiesFile = new File(fileURI); +// } catch (Exception e1) { +// e1.printStackTrace(); +// } +// +// try { +// fileURI = new URI("file://c:/moa3/tomcat8/conf/moa-id/moa-id.properties"); +// File propertiesFile = new File(fileURI); +// } catch (Exception e1) { +// e1.printStackTrace(); +// } +// +// try { +// fileURI = new URI("file:///c:/moa3/tomcat8/conf/moa-id/moa-id.properties"); +// File propertiesFile = new File(fileURI); +// } catch (Exception e1) { +// e1.printStackTrace(); +// } +// +// +// +// try { +// InputStream s = new FileInputStream("D:/idl_test/identity_link.xml"); +// Element idlTemplate = DOMUtils.parseXmlValidating(s); +// +// //resign IDL +// IdentityLinkReSigner identitylinkresigner = IdentityLinkReSigner.getInstance(); +// Element resignedilAssertion = identitylinkresigner.resignIdentityLink(idlTemplate, "IDLSigning"); +// IdentityLink identityLink = new IdentityLinkAssertionParser(resignedilAssertion).parseIdentityLink(); +// +// } catch (Exception e) { +// System.out.println(e.getMessage()); +// +// } +// +// String subjectName = "serialNumber=896929130327, givenName=OCSP, SN=Responder 03-1, CN=OCSP Responder 03-1, C=AT"; +// +// try { +// Name test = new RFC2253NameParser(subjectName).parse(); +// +// System.out.println(test.getRFC2253String()); +// +// } catch (RFC2253NameParserException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } // AuthenticationRole test = AuthenticationRoleFactory.buildFormPVPole("ecas-demo-EUROPEAN_COMMISSION(key=A\\,B)"); diff --git a/id/server/idserverlib/src/test/java/testBeans.xml b/id/server/idserverlib/src/test/java/testBeans.xml new file mode 100644 index 000000000..238a571cb --- /dev/null +++ b/id/server/idserverlib/src/test/java/testBeans.xml @@ -0,0 +1,130 @@ +<?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:p="http://www.springframework.org/schema/p" + 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="configPropertyDao" + class="at.gv.egovernment.moa.id.commons.db.dao.config.DatabaseConfigPropertyImpl"/> + + <bean id="moaidconfig" class="at.gv.egovernment.moa.id.commons.config.persistence.MOAIDConfigurationImpl" /> + + <bean name="config" id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> + <property name="dataSource" ref="dataSource" /> + <property name="jpaVendorAdapter" ref="jpaVendorAdapter" /> + <property name="persistenceUnitName" value="config" /> + </bean> + + <bean name="transactionManager" id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> + <property name="entityManagerFactory" ref="entityManagerFactory" /> + </bean> + <tx:annotation-driven transaction-manager="transactionManager"/> + + <bean id="RedisTransactionStorage" + class="at.gv.egovernment.moa.id.storage.RedisTransactionStorage"/> + + <bean id="DBTransactionStorage" + class="at.gv.egovernment.moa.id.storage.DBTransactionStorage"/> + + <!-- Redis Beans --> + <bean id="jedisConnFactory" + class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" + p:use-pool="true" + p:poolConfig-ref="jedisPoolConfig"/> + + <bean id="jedisPoolConfig" + class="redis.clients.jedis.JedisPoolConfig" + p:maxTotal="100" + p:maxIdle="10"/> + + <bean id="RedisStringSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" /> + <bean id="assertionStoreSerializer" class="org.springframework.data.redis.serializer.JacksonJsonRedisSerializer"> + <constructor-arg type="java.lang.Class" value="at.gv.egovernment.moa.id.commons.db.dao.session.AssertionStore"/> + </bean> + + <bean id="redisTemplate" + class="org.springframework.data.redis.core.RedisTemplate" + p:connection-factory-ref="jedisConnFactory" + p:value-serializer-ref="RedisStringSerializer" + p:key-serializer-ref="RedisStringSerializer" + p:enableTransactionSupport="true"/> + + <context:property-placeholder location="${moa.id.configuration}"/> + + <bean id="moaidauthconfig" class="at.gv.egovernment.moa.id.config.auth.PropertyBasedAuthConfigurationProvider"> + <constructor-arg value="#{systemProperties['moa.id.configuration']}"/> + </bean> + + <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" lazy-init="true" destroy-method="close"> + <aop:scoped-proxy/> + <property name="driverClassName" value="${configuration.hibernate.connection.driver_class}" /> + <property name="url" value="${configuration.hibernate.connection.url}"/> + <property name="username" value="${configuration.hibernate.connection.username}" /> + <property name="password" value="${configuration.hibernate.connection.password}" /> + + <property name="connectionProperties" value="${configuration.dbcp.connectionProperties}" /> + <property name="initialSize" value="${configuration.dbcp.initialSize}" /> + <property name="maxTotal" value="${configuration.dbcp.maxActive}" /> + <property name="maxIdle" value="${configuration.dbcp.maxIdle}" /> + <property name="minIdle" value="${configuration.dbcp.minIdle}" /> + <!-- property name="maxWait" value="${configuration.dbcp.maxWaitMillis}" / --> + <property name="testOnBorrow" value="${configuration.dbcp.testOnBorrow}" /> + <property name="testOnReturn" value="${configuration.dbcp.testOnReturn}" /> + <property name="testWhileIdle" value="${configuration.dbcp.testWhileIdle}" /> + <property name="validationQuery" value="${configuration.dbcp.validationQuery}" /> + </bean> + + <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> + <property name="showSql" value="${configuration.hibernate.show_sql}" /> + <property name="generateDdl" value="${configuration.jpaVendorAdapter.generateDdl}" /> + <property name="databasePlatform" value="${configuration.hibernate.dialect}" /> + </bean> + + <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> + <property name="corePoolSize" value="1" /> + <property name="maxPoolSize" value="50" /> + <property name="queueCapacity" value="50" /> + </bean> + + <bean id="sessionDataSource" class="org.apache.commons.dbcp2.BasicDataSource" lazy-init="true" destroy-method="close"> + <aop:scoped-proxy/> + <property name="driverClassName" value="${moasession.hibernate.connection.driver_class}" /> + <property name="url" value="${moasession.hibernate.connection.url}"/> + <property name="username" value="${moasession.hibernate.connection.username}" /> + <property name="password" value="${moasession.hibernate.connection.password}" /> + + <property name="connectionProperties" value="${moasession.dbcp.connectionProperties}" /> + <property name="initialSize" value="${moasession.dbcp.initialSize}" /> + <property name="maxTotal" value="${moasession.dbcp.maxActive}" /> + <property name="maxIdle" value="${moasession.dbcp.maxIdle}" /> + <property name="minIdle" value="${moasession.dbcp.minIdle}" /> + <!-- property name="maxWait" value="${moasession.dbcp.maxWaitMillis}" / --> + <property name="testOnBorrow" value="${moasession.dbcp.testOnBorrow}" /> + <property name="testOnReturn" value="${moasession.dbcp.testOnReturn}" /> + <property name="testWhileIdle" value="${moasession.dbcp.testWhileIdle}" /> + <property name="validationQuery" value="${moasession.dbcp.validationQuery}" /> + </bean> + + <bean id="sessionJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> + <property name="showSql" value="${moasession.hibernate.show_sql}" /> + <property name="generateDdl" value="${moasession.jpaVendorAdapter.generateDdl}" /> + <property name="databasePlatform" value="${moasession.hibernate.dialect}" /> + </bean> + + <bean name="sessionEntityManagerFactory" id="sessionEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> + <property name="dataSource" ref="sessionDataSource" /> + <property name="jpaVendorAdapter" ref="sessionJpaVendorAdapter" /> + <property name="persistenceUnitName" value="session" /> + </bean> + + <bean name="sessionTransactionManager" id="sessionTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> + <property name="entityManagerFactory" ref="sessionEntityManagerFactory" /> + </bean> +</beans>
\ No newline at end of file diff --git a/id/server/idserverlib/src/test/resources/at/gv/egovernment/moa/id/process/spring/test/SpringExpressionAwareProcessEngineTest-context.xml b/id/server/idserverlib/src/test/resources/at/gv/egovernment/moa/id/process/spring/test/SpringExpressionAwareProcessEngineTest-context.xml index bf47c0445..7d9db0ab7 100644 --- a/id/server/idserverlib/src/test/resources/at/gv/egovernment/moa/id/process/spring/test/SpringExpressionAwareProcessEngineTest-context.xml +++ b/id/server/idserverlib/src/test/resources/at/gv/egovernment/moa/id/process/spring/test/SpringExpressionAwareProcessEngineTest-context.xml @@ -1,9 +1,13 @@ <?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:task="http://www.springframework.org/schema/task" - xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> + 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"> <bean id="springElAwareExpressionEvaluator" class="at.gv.egovernment.moa.id.process.spring.SpringExpressionEvaluator" /> @@ -12,7 +16,7 @@ </bean> <bean id="TransactionStorage" - class="at.gv.egovernment.moa.id.storage.DBTransactionStorage"/> + class="at.gv.egovernment.moa.id.process.spring.test.DummyTransactionStorage"/> <bean id="ProcessInstanceStoreage" class="at.gv.egovernment.moa.id.process.dao.ProcessInstanceStoreDAOImpl"/> @@ -40,4 +44,5 @@ <bean id="ValidateSignedAuthBlockTask" class="at.gv.egovernment.moa.id.process.spring.test.task.ValidateSignedAuthBlockTask"/> + </beans> diff --git a/id/server/moa-id-commons/pom.xml b/id/server/moa-id-commons/pom.xml index ea9e06fd6..6b9591059 100644 --- a/id/server/moa-id-commons/pom.xml +++ b/id/server/moa-id-commons/pom.xml @@ -97,16 +97,18 @@ <groupId>iaik.prod</groupId> <artifactId>iaik_jce_full</artifactId> </dependency> - <dependency> - <groupId>iaik.prod</groupId> - <artifactId>iaik_moa</artifactId> - </dependency> + <dependency> + <groupId>MOA.id</groupId> + <artifactId>moa-spss-container</artifactId> + <version>${moa-id-version}</version> + </dependency> + <dependency> <groupId>iaik.prod</groupId> <artifactId>iaik_X509TrustManager</artifactId> </dependency> - + <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> @@ -143,11 +145,11 @@ <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> - <dependency> + <!-- dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>${hibernate.version}</version> - </dependency> + </dependency--> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> @@ -232,6 +234,11 @@ <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-tx</artifactId> + <version>${org.springframework.version}</version> + </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/MOAIDConstants.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/MOAIDConstants.java index 6726aacb5..6d573efe8 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/MOAIDConstants.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/MOAIDConstants.java @@ -40,11 +40,13 @@ public class MOAIDConstants { public static final String PREFIX_WPBK = "urn:publicid:gv.at:wbpk+"; public static final String PREFIX_STORK = "urn:publicid:gv.at:storkid+"; + public static final String PREFIX_EIDAS = "urn:publicid:gv.at:eidasid+"; public static final String IDENIFICATIONTYPE_FN = "FN"; public static final String IDENIFICATIONTYPE_ERSB = "ERSB"; public static final String IDENIFICATIONTYPE_ZVR = "ZVR"; public static final String IDENIFICATIONTYPE_STORK = "STORK"; + public static final String IDENIFICATIONTYPE_EIDAS = "eIDAS"; public static final String KEYBOXIDENTIFIER_SECURE = "SecureSignatureKeypair"; public static final String KEYBOXIDENTIFIER_CERTIFIED = "CertifiedKeypair"; @@ -61,16 +63,22 @@ public class MOAIDConstants { public static final List<String> ALLOWED_KEYBOXIDENTIFIER; public static final List<String> ALLOWED_REDIRECTTARGETNAMES; public static final List<String> ALLOWED_STORKATTRIBUTEPROVIDERS; + public static final List<String> ALLOWED_eIDAS_LOA; public static final List<String> JDBC_DRIVER_NEEDS_WORKAROUND; public static final String UNIQUESESSIONIDENTIFIER = "uniqueSessionIdentifier"; + public static final String eIDAS_LOA_LOW = "http://eidas.europa.eu/LoA/low"; + public static final String eIDAS_LOA_SUBSTANTIAL = "http://eidas.europa.eu/LoA/substantial"; + public static final String eIDAS_LOA_HIGH = "http://eidas.europa.eu/LoA/high"; + static { Hashtable<String, String> tmp = new Hashtable<String, String>(); tmp.put(IDENIFICATIONTYPE_FN, "Firmenbuchnummer"); tmp.put(IDENIFICATIONTYPE_ZVR, "Vereinsnummer"); tmp.put(IDENIFICATIONTYPE_ERSB, "ERsB Kennzahl"); tmp.put(IDENIFICATIONTYPE_STORK, "STORK"); + tmp.put(IDENIFICATIONTYPE_EIDAS, "eIDAS"); BUSINESSSERVICENAMES = Collections.unmodifiableMap(tmp); List<String> awbpk = new ArrayList<String>(); @@ -87,6 +95,12 @@ public class MOAIDConstants { keyboxIDs.add(KEYBOXIDENTIFIER_CERTIFIED); ALLOWED_KEYBOXIDENTIFIER = Collections.unmodifiableList(keyboxIDs); + List<String> eIDASLOA = new ArrayList<String>(); + eIDASLOA.add(eIDAS_LOA_LOW); + eIDASLOA.add(eIDAS_LOA_SUBSTANTIAL); + eIDASLOA.add(eIDAS_LOA_HIGH); + ALLOWED_eIDAS_LOA = Collections.unmodifiableList(eIDASLOA); + List<String> redirectTargets = new ArrayList<String>(); redirectTargets.add(REDIRECTTARGET_BLANK); redirectTargets.add(REDIRECTTARGET_PARENT); diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/AuthConfiguration.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/AuthConfiguration.java index fa08dcab6..d8938e353 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/AuthConfiguration.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/AuthConfiguration.java @@ -30,6 +30,16 @@ public interface AuthConfiguration extends ConfigurationProvider{ */ public String getBasicMOAIDConfiguration(final String key); + + /** + * Get a configuration value from basic file based MOA-ID configuration + * + * @param key configuration key + * @param defaultValue Default value if no value with this key is found + * @return configuration value + */ + public String getBasicMOAIDConfiguration(final String key, final String defaultValue); + public int getTransactionTimeOut(); public int getSSOCreatedTimeOut(); public int getSSOUpdatedTimeOut(); diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/IOAAuthParameters.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/IOAAuthParameters.java index be6d34275..1aea8d7b6 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/IOAAuthParameters.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/IOAAuthParameters.java @@ -152,7 +152,12 @@ public interface IOAAuthParameters { */ public boolean isShowStorkLogin(); - public Integer getQaaLevel(); + /** + * Return the eIDAS LoA which is minimum required + * + * @return eIDAS LoA as URL identifier + */ + public String getQaaLevel(); public boolean isRequireConsentForStorkAttributes(); diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/IRequest.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/IRequest.java index b23b4474b..25919a937 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/IRequest.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/IRequest.java @@ -24,6 +24,8 @@ package at.gv.egovernment.moa.id.commons.api; import java.util.Collection; +import org.opensaml.saml2.metadata.provider.MetadataProvider; + import at.gv.egovernment.moa.id.commons.api.exceptions.SessionDataStorageException; public interface IRequest { @@ -193,9 +195,10 @@ public interface IRequest { /** * This method get a Set of PVP 2.1 attribute, which are request by this pending-request. + * @param metadataProvider SAML2 Metadata Provider, or null if no metadata provider is required * * @return A set of PVP attribute names or null if no attributes are requested * or the Service Provider, which sends this request needs no attributes */ - public Collection<String> getRequestedAttributes(); + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider); } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/config/ConfigurationMigrationUtils.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/config/ConfigurationMigrationUtils.java index a221d30e4..8472d7c06 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/config/ConfigurationMigrationUtils.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/config/ConfigurationMigrationUtils.java @@ -32,6 +32,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import at.gv.egovernment.moa.id.commons.MOAIDConstants; import at.gv.egovernment.moa.id.commons.db.dao.config.deprecated.AttributeProviderPlugin; import at.gv.egovernment.moa.id.commons.db.dao.config.deprecated.AuthComponentGeneral; import at.gv.egovernment.moa.id.commons.db.dao.config.deprecated.AuthComponentOA; @@ -184,6 +185,10 @@ public class ConfigurationMigrationUtils { if (MOAIDConfigurationConstants.PREFIX_WPBK.startsWith(split[0]) && split.length >= 2) { result.put(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_TYPE, split[1]); result.put(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_VALUE, split[2]); + + } else if (MOAIDConfigurationConstants.PREFIX_EIDAS.startsWith(split[0]) && split.length >= 2) { + result.put(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_TYPE, MOAIDConfigurationConstants.IDENIFICATIONTYPE_EIDAS); + result.put(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_VALUE, split[1] + "+" + split[2]); } else if (MOAIDConfigurationConstants.PREFIX_STORK.startsWith(split[0]) && split.length >= 2) { result.put(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_TYPE, MOAIDConfigurationConstants.IDENIFICATIONTYPE_STORK); @@ -350,10 +355,11 @@ public class ConfigurationMigrationUtils { else result.put(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_ENABLED, Boolean.FALSE.toString()); - if (config.getQaa() != null) - result.put(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_MINQAALEVEL, config.getQaa().toString()); + if (config.geteIDAS_LOA() != null) + result.put(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_MINQAALEVEL, config.geteIDAS_LOA()); else - result.put(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_MINQAALEVEL, "4"); + result.put(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_MINQAALEVEL, + MOAIDConstants.eIDAS_LOA_HIGH); // fetch vidp config @@ -759,9 +765,15 @@ public class ConfigurationMigrationUtils { if (oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_TYPE) != null && oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_VALUE) != null) { - if (oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_TYPE).equals(MOAIDConfigurationConstants.IDENIFICATIONTYPE_STORK)) { + + if (oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_TYPE).equals(MOAIDConfigurationConstants.IDENIFICATIONTYPE_EIDAS)) { + idnumber.setValue(MOAIDConfigurationConstants.PREFIX_EIDAS + oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_VALUE)); + idnumber.setType(MOAIDConfigurationConstants.BUSINESSSERVICENAMES.get(oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_TYPE))); + + } else if (oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_TYPE).equals(MOAIDConfigurationConstants.IDENIFICATIONTYPE_STORK)) { idnumber.setValue(MOAIDConfigurationConstants.PREFIX_STORK + "AT" + "+" + oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_VALUE)); idnumber.setType(MOAIDConfigurationConstants.BUSINESSSERVICENAMES.get(oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_TYPE))); + } else { idnumber.setValue(MOAIDConfigurationConstants.PREFIX_WPBK + oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_TYPE) + "+" + oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_VALUE)); idnumber.setType(MOAIDConfigurationConstants.BUSINESSSERVICENAMES.get(oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_TYPE))); @@ -953,7 +965,7 @@ public class ConfigurationMigrationUtils { // transfer the incoming data to the database model stork.setStorkLogonEnabled(Boolean.parseBoolean(oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_ENABLED))); if (MiscUtil.isNotEmpty(oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_MINQAALEVEL))) - stork.setQaa(Integer.valueOf(oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_MINQAALEVEL))); + stork.seteIDAS_LOA(oa.get(MOAIDConfigurationConstants.SERVICE_AUTH_STORK_MINQAALEVEL)); if (MiscUtil.isNotEmpty(oa.get(MOAIDConfigurationConstants.PREFIX_MOAID_SERVICES)) && oa.get(MOAIDConfigurationConstants.PREFIX_MOAID_SERVICES).equals(MOAIDConfigurationConstants.PREFIX_VIDP)) @@ -1458,11 +1470,11 @@ public class ConfigurationMigrationUtils { try { result.put(MOAIDConfigurationConstants.GENERAL_AUTH_STORK_QAA, - String.valueOf(stork.getQualityAuthenticationAssuranceLevel())); + stork.getGeneral_eIDAS_LOA()); } catch(NullPointerException e) { result.put(MOAIDConfigurationConstants.GENERAL_AUTH_STORK_QAA, - String.valueOf(4)); + MOAIDConstants.eIDAS_LOA_HIGH); } } @@ -1705,6 +1717,12 @@ public class ConfigurationMigrationUtils { } + //set eIDAS default LoA from general configuration + String eIDASDefaultLOA = moaconfig.get(MOAIDConfigurationConstants.GENERAL_AUTH_STORK_QAA); + if (MiscUtil.isNotEmpty(eIDASDefaultLOA)) + stork.setGeneral_eIDAS_LOA(eIDASDefaultLOA); + + Map<String, StorkAttribute> attrMap = new HashMap<String, StorkAttribute>(); Map<String, CPEPS> cpepsMap = new HashMap<String, CPEPS>(); diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/config/SpringProfileConstants.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/config/SpringProfileConstants.java new file mode 100644 index 000000000..14824b1f8 --- /dev/null +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/config/SpringProfileConstants.java @@ -0,0 +1,8 @@ +package at.gv.egovernment.moa.id.commons.config; + +public final class SpringProfileConstants { + + public static final String ADVANCED_LOG = "advancedLogOn"; + public static final String REDIS_BACKEND = "redisBackend"; + public static final String DB_BACKEND = "dbBackend"; +} diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/MOASessionDBUtils.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/MOASessionDBUtils.java index ecb13ef34..5cdd607ac 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/MOASessionDBUtils.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/MOASessionDBUtils.java @@ -24,62 +24,34 @@ package at.gv.egovernment.moa.id.commons.db; import java.util.Properties; -import org.apache.commons.lang3.StringUtils; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; -import org.hibernate.service.ServiceRegistry; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.logging.Logger; -public final class MOASessionDBUtils { +@Transactional("sessionTransactionManager") +public class MOASessionDBUtils { - private static SessionFactory sessionFactory; - private static ServiceRegistry serviceRegistry; - - @SuppressWarnings("rawtypes") - private static final ThreadLocal THREAD_LOCAL = new ThreadLocal(); - private static boolean automaticSessionHandling = false; - private static final String[] AUTOMATIC_SESSION_HANDLING_VALUES = new String[] { "jta", "thread" }; - private static final String SESSION_HANDLING_KEY = "hibernate.current_session_context_class"; - - protected MOASessionDBUtils() { } + private SessionFactory sessionFactory; + + @Autowired + @Qualifier("sessionSessionFactory") + public void setSessionFactory(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } - public static void initHibernate(Configuration config, Properties hibernateProperties) { - - String scm = StringUtils.trimToNull(hibernateProperties.getProperty(SESSION_HANDLING_KEY)); - if (scm != null) { - automaticSessionHandling = scm.indexOf(AUTOMATIC_SESSION_HANDLING_VALUES[0]) != -1 || scm.indexOf(AUTOMATIC_SESSION_HANDLING_VALUES[1]) != -1; - } - Logger.debug("Evaluating hibernate property \"" + SESSION_HANDLING_KEY + "\"."); - if (automaticSessionHandling) { - Logger.info("Hibernate is automatically handling session context management."); - } else { - Logger.info("Hibernate is NOT automatically handling session context management. Using build-in ThreadLocal session handling."); - } - try { - //Create the SessionFactory - Logger.debug("Creating initial MOASession session factory..."); - - config.configure("hibernate_moasession.cfg.xml"); - //serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry(); - - serviceRegistry = new StandardServiceRegistryBuilder(). - applySettings(config.getProperties()).build(); - - sessionFactory = config.buildSessionFactory(serviceRegistry); - Logger.debug("Initial MOASession session factory successfully created."); - - } catch (Throwable ex) { - Logger.error("Initial MOASession session factory creation failed: " + ex.getMessage()); - throw new ExceptionInInitializerError(ex); - } - } + public void initHibernate(Configuration config, Properties hibernateProperties) { + + } /** * Checks if a session factory is currently available. If necessary a new @@ -89,102 +61,32 @@ public final class MOASessionDBUtils { * @throws HibernateException * thrown if a hibernate error occurs */ - public static Session getCurrentSession() { - if (automaticSessionHandling) { - return sessionFactory.getCurrentSession(); - } - Session session = (Session) THREAD_LOCAL.get(); - // Open a new Session, if this Thread has none yet - if (session == null || !session.isConnected()) { - session = getNewSession(); - } - return session; - } - - @SuppressWarnings("unchecked") - public static Session getNewSession() { - if (automaticSessionHandling) { - Logger.warn("Session is being automatically handled by hibernate. Therefore this session maybe not being newly created. Use HibernateUtil.getCurrentSession() instead."); - return sessionFactory.getCurrentSession(); - } - Session session = (Session) THREAD_LOCAL.get(); - if (session != null) { - Logger.warn("Previous MOASession session has not been closed; closing session now."); - closeSession(); - } - Logger.debug("Opening new MOASession hibernate session..."); - try { - session = sessionFactory.openSession(); - THREAD_LOCAL.set(session); - } catch (HibernateException hex) { - Logger.error(hex.getMessage()); - } - return session; - } - - /** - * Closes the current session. - * - * @throws HibernateException - * thrown if session is already closed or a hibernate error - * occurs. - */ - @SuppressWarnings("unchecked") - public static void closeSession() { - if (automaticSessionHandling) { - Logger.warn("Session is being automatically handled by hibernate. Therefore the current session cannot be closed on demand."); - return; - } - Logger.debug("Closing current MOASession hibernate session..."); - Session session = (Session) THREAD_LOCAL.get(); - THREAD_LOCAL.set(null); - if (session != null) { - try { - session.close(); - - } catch (HibernateException hex) { - Logger.error(hex.getMessage()); - } - } + public Session getCurrentSession() { + return sessionFactory.getCurrentSession(); } - public static boolean saveOrUpdate(Object dbo) throws MOADatabaseException { - Transaction tx = null; + public boolean saveOrUpdate(Object dbo) throws MOADatabaseException { try { - Session session = MOASessionDBUtils.getCurrentSession(); - - synchronized (session) { - tx = session.beginTransaction(); - session.saveOrUpdate(dbo); - tx.commit(); - } - return true; + Session session = sessionFactory.getCurrentSession(); + session.merge(dbo); + return true; } catch(HibernateException e) { - Logger.warn("Error during MOASession database saveOrUpdate. Rollback.", e); - if (tx != null) - tx.rollback(); + Logger.warn("Error during MOASession database saveOrUpdate.", e); + throw new MOADatabaseException(e); } } - public static boolean delete(Object dbo) { - Transaction tx = null; + public boolean delete(Object dbo) { + try { - Session session = MOASessionDBUtils.getCurrentSession(); - - synchronized (session) { - tx = session.beginTransaction(); - session.delete(dbo); - tx.commit(); - } - + Session session = sessionFactory.getCurrentSession(); + session.delete(dbo); return true; } catch(HibernateException e) { - Logger.warn("Error during MOASession database delete. Rollback.", e); - if (tx != null) - tx.rollback(); + Logger.warn("Error during MOASession database delete. Rollback."); return false; } } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/StatisticLogDBUtils.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/StatisticLogDBUtils.java index 7e031cc76..51bb0eb6d 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/StatisticLogDBUtils.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/StatisticLogDBUtils.java @@ -24,169 +24,65 @@ package at.gv.egovernment.moa.id.commons.db; import java.util.Properties; -import org.apache.commons.lang3.StringUtils; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; -import org.hibernate.Transaction; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; -import org.hibernate.service.ServiceRegistry; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.transaction.annotation.Transactional; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.logging.Logger; -public final class StatisticLogDBUtils { +@Transactional("statisticLogTransactionManager") +public class StatisticLogDBUtils { + + private SessionFactory sessionFactory; - private static SessionFactory sessionFactory; - private static ServiceRegistry serviceRegistry; - - @SuppressWarnings("rawtypes") - private static final ThreadLocal THREAD_LOCAL_STATISTIC = new ThreadLocal(); - private static boolean automaticSessionHandling = false; + @Autowired + @Qualifier("statisticLogSessionFactory") + public void setstatisticLogSessionFactory(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } - private static final String[] AUTOMATIC_SESSION_HANDLING_VALUES = new String[] { "jta", "thread" }; - private static final String SESSION_HANDLING_KEY = "hibernate.current_session_context_class"; - - protected StatisticLogDBUtils() { } public static void initHibernate(Configuration config, Properties hibernateProperties) { - String scm = StringUtils.trimToNull(hibernateProperties.getProperty(SESSION_HANDLING_KEY)); - if (scm != null) { - automaticSessionHandling = scm.indexOf(AUTOMATIC_SESSION_HANDLING_VALUES[0]) != -1 || scm.indexOf(AUTOMATIC_SESSION_HANDLING_VALUES[1]) != -1; - } - Logger.debug("Evaluating hibernate property \"" + SESSION_HANDLING_KEY + "\"."); - if (automaticSessionHandling) { - Logger.info("Hibernate is automatically handling session context management."); - } else { - Logger.info("Hibernate is NOT automatically handling session context management. Using build-in ThreadLocal session handling."); - } - try { - //Create the SessionFactory - Logger.debug("Creating initial StatisicLogger session factory..."); - - config.configure("hibernate_statistic.cfg.xml"); - //serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry(); - - serviceRegistry = new StandardServiceRegistryBuilder(). - applySettings(config.getProperties()).build(); - - sessionFactory = config.buildSessionFactory(serviceRegistry); - Logger.debug("Initial StatisicLogger session factory successfully created."); - - } catch (Throwable ex) { - Logger.error("Initial StatisicLogger session factory creation failed: " + ex.getMessage()); - throw new ExceptionInInitializerError(ex); - } - } - - /** - * Checks if a session factory is currently available. If necessary a new - * session factory is created. - * - * @return current (or new) session factory - * @throws HibernateException - * thrown if a hibernate error occurs - */ - public static Session getCurrentSession() { - if (automaticSessionHandling) { - return sessionFactory.getCurrentSession(); - } - Session session = (Session) THREAD_LOCAL_STATISTIC.get(); - // Open a new Session, if this Thread has none yet - if (session == null || !session.isConnected()) { - session = getNewSession(); - } - return session; } - @SuppressWarnings("unchecked") - public static Session getNewSession() { - if (automaticSessionHandling) { - Logger.warn("Session is being automatically handled by hibernate. Therefore this session maybe not being newly created. Use HibernateUtil.getCurrentSession() instead."); - return sessionFactory.getCurrentSession(); - } - Session session = (Session) THREAD_LOCAL_STATISTIC.get(); - if (session != null) { - Logger.warn("Previous StatisicLogger session has not been closed; closing session now."); - closeSession(); - } - Logger.debug("Opening new StatisicLogger hibernate session..."); - try { - session = sessionFactory.openSession(); - THREAD_LOCAL_STATISTIC.set(session); - } catch (HibernateException hex) { - Logger.error(hex.getMessage()); - } - return session; - } - - /** - * Closes the current session. - * - * @throws HibernateException - * thrown if session is already closed or a hibernate error - * occurs. - */ - @SuppressWarnings("unchecked") - public static void closeSession() { - if (automaticSessionHandling) { - Logger.warn("Session is being automatically handled by hibernate. Therefore the current session cannot be closed on demand."); - return; - } - Logger.debug("Closing current StatisicLogger hibernate session..."); - Session session = (Session) THREAD_LOCAL_STATISTIC.get(); - THREAD_LOCAL_STATISTIC.set(null); - if (session != null) { - try { - session.close(); - - } catch (HibernateException hex) { - Logger.error(hex.getMessage()); - } - } - } - - public static boolean saveOrUpdate(Object dbo) throws MOADatabaseException { - Transaction tx = null; - try { - Session session = StatisticLogDBUtils.getCurrentSession(); - - synchronized (session) { - tx = session.beginTransaction(); - session.saveOrUpdate(dbo); - tx.commit(); - } - - Logger.info("Insert advanced statistic log entry into database"); - return true; - - } catch(HibernateException e) { - Logger.warn("Error during StatisicLogger database saveOrUpdate. Rollback.", e); - tx.rollback(); - throw new MOADatabaseException(e); - } - } + public boolean saveOrUpdate(Object dbo) throws MOADatabaseException { - public static boolean delete(Object dbo) { - Transaction tx = null; - try { - Session session = StatisticLogDBUtils.getCurrentSession(); - - synchronized (session) { - tx = session.beginTransaction(); - session.delete(dbo); - tx.commit(); - } - - return true; + try { + Session session = sessionFactory.getCurrentSession(); + session.saveOrUpdate(dbo); + //session.persist(dbo); + return true; } catch(HibernateException e) { - Logger.warn("Error during StatisicLogger database delete. Rollback.", e); - tx.rollback(); - return false; + Logger.warn("Error during StatisicLogger database saveOrUpdate.", e); + + throw new MOADatabaseException(e); } + } + + public boolean delete(Object dbo) { + try { + Session session = sessionFactory.getCurrentSession(); + session.delete(dbo); + return true; + + } catch(HibernateException e) { + Logger.warn("Error during StatisicLogger database delete. Rollback."); + return false; + } + } + + + public Session getCurrentSession() { + // TODO Auto-generated method stub + return sessionFactory.getCurrentSession(); + } } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/config/deprecated/OASTORK.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/config/deprecated/OASTORK.java index 397fd828b..0f76c4e63 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/config/deprecated/OASTORK.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/config/deprecated/OASTORK.java @@ -11,29 +11,21 @@ package at.gv.egovernment.moa.id.commons.db.dao.config.deprecated; import java.io.Serializable; import java.util.ArrayList; import java.util.List; -import javax.persistence.Basic; + import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Inheritance; -import javax.persistence.InheritanceType; -import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.OneToMany; -import javax.persistence.Table; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import com.sun.tools.xjc.runtime.ZeroOneBooleanAdapter; + import org.jvnet.jaxb2_commons.lang.Equals; import org.jvnet.jaxb2_commons.lang.EqualsStrategy; import org.jvnet.jaxb2_commons.lang.HashCode; @@ -43,6 +35,8 @@ import org.jvnet.jaxb2_commons.lang.JAXBHashCodeStrategy; import org.jvnet.jaxb2_commons.locator.ObjectLocator; import org.jvnet.jaxb2_commons.locator.util.LocatorUtils; +import com.sun.tools.xjc.runtime.ZeroOneBooleanAdapter; + /** * <p>Java class for anonymous complex type. @@ -110,6 +104,9 @@ public class OASTORK @XmlAttribute(name = "Hjid") protected Long hjid; + @XmlTransient + protected String eIDAS_LOA = null; + /** * Gets the value of the storkLogonEnabled property. * @@ -162,7 +159,23 @@ public class OASTORK this.qaa = value; } + + /** + * @return the eIDAS_LOA + */ + public String geteIDAS_LOA() { + return eIDAS_LOA; + } + + /** + * @param eIDAS_LOA the eIDAS_LOA to set + */ + public void seteIDAS_LOA(String eIDAS_LOA) { + this.eIDAS_LOA = eIDAS_LOA; + } + + /** * Gets the value of the oaAttributes property. * * <p> diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/config/deprecated/STORK.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/config/deprecated/STORK.java index 59b300e95..bcd159702 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/config/deprecated/STORK.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/config/deprecated/STORK.java @@ -11,25 +11,18 @@ package at.gv.egovernment.moa.id.commons.db.dao.config.deprecated; import java.io.Serializable; import java.util.ArrayList; import java.util.List; -import javax.persistence.Basic; + import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Inheritance; -import javax.persistence.InheritanceType; -import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; -import javax.persistence.Table; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; + import org.jvnet.jaxb2_commons.lang.Equals; import org.jvnet.jaxb2_commons.lang.EqualsStrategy; import org.jvnet.jaxb2_commons.lang.HashCode; @@ -94,6 +87,9 @@ public class STORK @XmlAttribute(name = "Hjid") protected Long hjid; + @XmlTransient + protected String general_eIDAS_LOA = null; + /** * Gets the value of the cpeps property. * @@ -257,7 +253,21 @@ public class STORK this.hjid = value; } - public boolean equals(ObjectLocator thisLocator, ObjectLocator thatLocator, Object object, EqualsStrategy strategy) { + /** + * @return the general_eIDAS_LOA + */ + public String getGeneral_eIDAS_LOA() { + return general_eIDAS_LOA; + } + + /** + * @param general_eIDAS_LOA the general_eIDAS_LOA to set + */ + public void setGeneral_eIDAS_LOA(String general_eIDAS_LOA) { + this.general_eIDAS_LOA = general_eIDAS_LOA; + } + + public boolean equals(ObjectLocator thisLocator, ObjectLocator thatLocator, Object object, EqualsStrategy strategy) { if (!(object instanceof STORK)) { return false; } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AssertionStore.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AssertionStore.java index 46683a928..4c6cd16c0 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AssertionStore.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AssertionStore.java @@ -37,6 +37,8 @@ import javax.persistence.Table; import org.hibernate.annotations.DynamicUpdate; +import com.fasterxml.jackson.annotation.JsonCreator; + @Entity @@ -48,11 +50,22 @@ import org.hibernate.annotations.DynamicUpdate; }) public class AssertionStore implements Serializable{ + /** + * + */ + private static final long serialVersionUID = 2804964892915004185L; + + + + @JsonCreator + public AssertionStore(){ + + } + - private static final long serialVersionUID = 1L; @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id", unique=true, nullable=false) private long id; diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AuthenticatedSessionStore.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AuthenticatedSessionStore.java index 128dd79df..eeaf03544 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AuthenticatedSessionStore.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AuthenticatedSessionStore.java @@ -59,7 +59,9 @@ import org.hibernate.annotations.DynamicUpdate; @NamedQuery(name="getMOASessionWithNameIDandOAID", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore join fetch authenticatedsessionstore.activeOAsessions activeOAsessions where activeOAsessions.oaurlprefix = :oaID and activeOAsessions.userNameID = :nameID"), @NamedQuery(name="getInterfederatedIDPForAttributeQueryWithSessionID", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore join fetch authenticatedsessionstore.inderfederation inderfederations where inderfederations.attributesRequested is false and authenticatedsessionstore.sessionid = :sessionID"), @NamedQuery(name="getInterfederatedIDPForSSOWithSessionID", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore join fetch authenticatedsessionstore.inderfederation inderfederations where inderfederations.attributesRequested is true and inderfederations.storeSSOInformation is true and authenticatedsessionstore.sessionid = :sessionID order by inderfederations.QAALevel DESC"), - @NamedQuery(name="getInterfederatedIDPForSSOWithSessionIDIDPID", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore join fetch authenticatedsessionstore.inderfederation inderfederations where inderfederations.attributesRequested is true and authenticatedsessionstore.sessionid = :sessionID and inderfederations.idpurlprefix = :idpID") + @NamedQuery(name="getInterfederatedIDPForSSOWithSessionIDIDPID", query = "select authenticatedsessionstore from AuthenticatedSessionStore authenticatedsessionstore join fetch authenticatedsessionstore.inderfederation inderfederations where inderfederations.attributesRequested is true and authenticatedsessionstore.sessionid = :sessionID and inderfederations.idpurlprefix = :idpID"), + @NamedQuery(name="getAllActiveOAsForSessionID", query = "select activeOAsessions from AuthenticatedSessionStore authenticatedsessionstore join authenticatedsessionstore.activeOAsessions activeOAsessions where authenticatedsessionstore.sessionid = :sessionID "), + @NamedQuery(name="getAllActiveIDPsForSessionID", query = "select inderfederation from AuthenticatedSessionStore authenticatedsessionstore join authenticatedsessionstore.inderfederation inderfederation where authenticatedsessionstore.sessionid = :sessionID ") }) public class AuthenticatedSessionStore implements Serializable{ diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/statistic/StatisticLog.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/statistic/StatisticLog.java index 97f26812f..ba48f8caf 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/statistic/StatisticLog.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/statistic/StatisticLog.java @@ -39,7 +39,7 @@ import org.hibernate.annotations.DynamicUpdate; @Entity -@DynamicUpdate(value=true) +//@DynamicUpdate(value=true) @Table(name = "statisticlog") @NamedQueries({ @NamedQuery(name="getAllEntriesNotBeforeTimeStamp", query = "select statisiclog from StatisticLog statisiclog where statisiclog.timestamp > :timeout") diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/MOAHttpProtocolSocketFactory.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/MOAHttpProtocolSocketFactory.java index 2ade63c1c..142e9a23a 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/MOAHttpProtocolSocketFactory.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/MOAHttpProtocolSocketFactory.java @@ -22,15 +22,12 @@ */ package at.gv.egovernment.moa.id.commons.utils; -import iaik.pki.PKIException; - import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.security.GeneralSecurityException; -import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import org.apache.commons.httpclient.ConnectTimeoutException; @@ -39,7 +36,7 @@ import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; import at.gv.egovernment.moa.id.commons.ex.MOAHttpProtocolSocketFactoryException; import at.gv.egovernment.moa.id.commons.utils.ssl.SSLConfigurationException; -import at.gv.egovernment.moa.id.commons.utils.ssl.SSLUtils; +import iaik.pki.PKIException; /** * @author tlenz @@ -62,7 +59,7 @@ public class MOAHttpProtocolSocketFactory implements SecureProtocolSocketFactory super(); try { - this.sslfactory = SSLUtils.getSSLSocketFactory( + this.sslfactory = at.gv.egovernment.moa.id.commons.utils.ssl.SSLUtils.getSSLSocketFactory( url, certStoreRootDirParam, trustStoreURL, diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/CertStoreConfigurationImpl.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/CertStoreConfigurationImpl.java index 00e750f58..d65cea08c 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/CertStoreConfigurationImpl.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/CertStoreConfigurationImpl.java @@ -46,14 +46,16 @@ package at.gv.egovernment.moa.id.commons.utils.ssl; +import java.io.File; +import java.util.Collections; +import java.util.Set; + import at.gv.egovernment.moa.logging.Logger; import iaik.pki.store.certstore.CertStoreConfiguration; import iaik.pki.store.certstore.CertStoreParameters; import iaik.pki.store.certstore.CertStoreTypes; import iaik.pki.store.certstore.directory.DirectoryCertStoreParameters; -import java.io.File; - /** * Implementation of interface needed to initialize an IAIK JSSE <code>TrustManager</code> * @@ -128,7 +130,7 @@ public class CertStoreConfigurationImpl extends ObservableImpl * @see iaik.pki.store.certstore.directory.DirectoryCertStoreParameters#createNew() */ public boolean createNew() { - return false; + return true; } /** @@ -153,4 +155,14 @@ public class CertStoreConfigurationImpl extends ObservableImpl return CertStoreTypes.DIRECTORY; } + /* (non-Javadoc) + * @see iaik.pki.store.certstore.directory.DirectoryCertStoreParameters#getVirtualStores() + */ + @Override + public Set getVirtualStores() { + //TODO: only for Testing and not complete !!!Ask Harald !!!! + return Collections.EMPTY_SET; + + } + } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOAIDTrustManager.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOAIDTrustManager.java index eaef3f1d4..e0304f928 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOAIDTrustManager.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOAIDTrustManager.java @@ -57,9 +57,14 @@ import java.util.ArrayList; import java.util.List; import at.gv.egovernment.moa.logging.Logger; -import at.gv.egovernment.moa.logging.LoggingContext; -import at.gv.egovernment.moa.logging.LoggingContextManager; - +import at.gv.egovernment.moaspss.logging.LoggingContext; +import at.gv.egovernment.moaspss.logging.LoggingContextManager; +import iaik.logging.TransactionId; +import iaik.logging.impl.TransactionIdImpl; +import iaik.pki.PKIConfiguration; +import iaik.pki.PKIException; +import iaik.pki.PKIFactory; +import iaik.pki.PKIProfile; import iaik.pki.jsse.IAIKX509TrustManager; /** @@ -95,14 +100,14 @@ public class MOAIDTrustManager extends IAIKX509TrustManager { * Fixes a bug occuring in the case MOA-SP is called by API. * In this case, IAIKX509TrustManager uses the LogginConfig of MOA-SP. * This method must be called before a MOAIDTrustManager is constructed, - * from every thread. - */ + * from every thread. + */ public static void initializeLoggingContext() { if (LoggingContextManager.getInstance().getLoggingContext() == null) LoggingContextManager.getInstance().setLoggingContext( new LoggingContext(Thread.currentThread().getName())); } - + /** * Builds an Array of accepted server certificates from an URL, @@ -161,4 +166,36 @@ public class MOAIDTrustManager extends IAIKX509TrustManager { { return true; } + + public void init(PKIConfiguration pkiConfig, PKIProfile pkiProfile) throws PKIException { + if (pkiProfile == null) { + throw new NullPointerException("pkiConfig parameter must not be null"); + + } + + TransactionId tid = new TransactionIdImpl("Init"); + log_.info(tid, "Setting up IAIKX509TrustManager", null); + if (pkiConfig != null) { + PKIFactory.getInstance().configure(pkiConfig, tid); +// log_.info(tid, "Registering LDAP protocol handler", null); +// String protocolHandlers = +// System.getProperty("java.protocol.handler.pkgs"); +// if (protocolHandlers == null) { +// protocolHandlers = "iaik.pki"; +// +// } else { +// protocolHandlers = protocolHandlers + "|iaik.pki"; +// +// } +// +// System.setProperty("java.protocol.handler.pkgs", protocolHandlers); +// log_.info(tid, "Registered protocol handlers: " + protocolHandlers, null); + + } + + pkiProfile_ = pkiProfile; + pkiFactory_ = PKIFactory.getInstance(); + initialized_ = true; + } + } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/PKIConfigurationImpl.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/PKIConfigurationImpl.java index 5d8c7a54e..3eb4707c8 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/PKIConfigurationImpl.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/PKIConfigurationImpl.java @@ -60,6 +60,10 @@ import iaik.pki.store.revocation.archive.ArchiveConfiguration; * @version $Id$ */ public class PKIConfigurationImpl implements PKIConfiguration { + + private static final int TIMEOUT_READ = 60; //[sec] + private static final int TIMEOUT_CONNECTION = 60; //[sec] + /** The configuration for the CertStore */ private CertStoreConfiguration certStoreConfiguration; /** The configuration for the RevocationChecks */ @@ -108,11 +112,19 @@ public class PKIConfigurationImpl implements PKIConfiguration { } /* (non-Javadoc) - * @see iaik.pki.PKIConfiguration#getTimeout() + * @see iaik.pki.PKIConfiguration#getConnectTimeout() */ - public int getTimeout() { - // TODO Auto-generated method stub - return 0; +@Override +public int getConnectTimeout() { + return TIMEOUT_CONNECTION * 1000; +} + +/* (non-Javadoc) + * @see iaik.pki.PKIConfiguration#getReadTimeout() + */ +@Override +public int getReadTimeout() { + return TIMEOUT_READ * 1000; } } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/PKIProfileImpl.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/PKIProfileImpl.java index 59994a257..a34fa9b8b 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/PKIProfileImpl.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/PKIProfileImpl.java @@ -96,13 +96,6 @@ public class PKIProfileImpl extends ObservableImpl } /** - * @see iaik.pki.PKIProfile#autoAddCertificates() - */ - public boolean autoAddCertificates() { - return true; - } - - /** * @see iaik.pki.PKIProfile#getRevocationProfile() */ public RevocationProfile getRevocationProfile() { @@ -227,4 +220,22 @@ public class PKIProfileImpl extends ObservableImpl public void setId(String id) { this.id = id; } + +/* (non-Javadoc) + * @see iaik.pki.PKIProfile#autoAddCertificates() + */ +@Override +public int autoAddCertificates() { + //TODO: ask harald!!!!! + return 1; +} + +/* (non-Javadoc) + * @see iaik.pki.PKIProfile#getIndirectRevocationTrustStoreProfile() + */ +@Override +public TrustStoreProfile getIndirectRevocationTrustStoreProfile() { + //TODO: ask harald!!!!! + return null; +} } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/RevocationConfigurationImpl.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/RevocationConfigurationImpl.java index b5e0543db..449f77209 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/RevocationConfigurationImpl.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/RevocationConfigurationImpl.java @@ -46,13 +46,14 @@ package at.gv.egovernment.moa.id.commons.utils.ssl; -import iaik.pki.revocation.RevocationConfiguration; - import java.security.cert.X509Certificate; import java.util.Collections; import java.util.Date; import java.util.Set; +import iaik.pki.revocation.RevocationConfiguration; +import iaik.pki.revocation.dbcrl.config.DBCrlConfig; + /** * Implementation of interface needed to initialize an IAIK JSSE <code>TrustManager</code> * @author Paul Ivancsics @@ -81,4 +82,43 @@ public class RevocationConfigurationImpl extends ObservableImpl implements Revoc return null; } +/* (non-Javadoc) + * @see iaik.pki.revocation.RevocationConfiguration#getKeepRevocationInfo() + */ +@Override +public boolean getKeepRevocationInfo() { + return false; +} + +/* (non-Javadoc) + * @see iaik.pki.revocation.RevocationConfiguration#getPositiveOCSPResponders() + */ +@Override +public Set getPositiveOCSPResponders() { + +// //TODO: !!!!! ASK Harald !!!!! +// Map<String, String> test = new HashMap<String, String>(); +// test.put("ALL", "ALL"); +// return test.keySet(); + + return Collections.EMPTY_SET; +} + +/* (non-Javadoc) + * @see iaik.pki.revocation.RevocationConfiguration#skipIndirectCRLCheckForAlternativeDistributionPoints() + */ +@Override +public boolean skipIndirectCRLCheckForAlternativeDistributionPoints() { + //TODO: !!!!! ASK Harald !!!!! + return false; +} + +/* (non-Javadoc) + * @see iaik.pki.revocation.RevocationConfiguration#getDataBaseCRLConfig() + */ +@Override +public DBCrlConfig getDataBaseCRLConfig() { + return null; +} + } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/SSLUtils.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/SSLUtils.java index 68437a04d..6fa4595d8 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/SSLUtils.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/SSLUtils.java @@ -46,25 +46,27 @@ package at.gv.egovernment.moa.id.commons.utils.ssl; -import iaik.pki.PKIConfiguration; -import iaik.pki.PKIException; -import iaik.pki.PKIFactory; -import iaik.pki.PKIProfile; -import iaik.pki.jsse.IAIKX509TrustManager; -import iaik.security.provider.IAIK; - import java.io.IOException; import java.security.GeneralSecurityException; +import java.security.KeyStore; import java.security.Security; import java.util.HashMap; import java.util.Map; import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.KeyStoreUtils; +import iaik.pki.PKIConfiguration; +import iaik.pki.PKIException; +import iaik.pki.PKIFactory; +import iaik.pki.PKIProfile; +//import iaik.pki.jsse.IAIKX509TrustManager; +import iaik.security.provider.IAIK; /** @@ -136,7 +138,7 @@ public class SSLUtils { acceptedServerCertURL, checkRevocation); - KeyManager[] kms = at.gv.egovernment.moa.util.SSLUtils.getKeyManagers( + KeyManager[] kms = getKeyManagers( clientKeyStoreType, clientKeyStoreURL, clientKeyStorePassword); SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(kms, tms, null); @@ -154,6 +156,68 @@ public class SSLUtils { } /** + * Loads the client key store from file and gets the + * <code>KeyManager</code>s from a default <code>KeyManagerFactory</code>, + * initialized from the given client key store. + * @param clientKeyStoreType key store type of <code>clientKeyStore</code> + * @param clientKeyStoreURL URL of key store containing keys to be used for + * client authentication; if <code>null</code>, the default key store will be utilized + * @param clientKeyStorePassword password used to check the integrity of the client key store; + * if <code>null</code>, it will not be checked + * @return <code>KeyManager</code>s to be used for creating an + * <code>SSLSocketFactory</code> utilizing the given client key store + * @throws IOException thrown while reading from the key store file + * @throws GeneralSecurityException thrown while initializing the + * default <code>KeyManagerFactory</code> + */ + public static KeyManager[] getKeyManagers ( + String clientKeyStoreType, + String clientKeyStoreURL, + String clientKeyStorePassword) + throws IOException, GeneralSecurityException { + + if (clientKeyStoreURL == null) + return null; + + // Set up the KeyStore to use. We need to load the file into + // a KeyStore instance. + KeyStore clientKeyStore = KeyStoreUtils.loadKeyStore( + clientKeyStoreType, clientKeyStoreURL, clientKeyStorePassword); + return getKeyManagers(clientKeyStore, clientKeyStorePassword); + } + /** + * Gets the <code>KeyManager</code>s from a default <code>KeyManagerFactory</code>, + * initialized from the given client key store. + * @param clientKeyStore client key store + * @param clientKeyStorePassword if provided, it will be used to check + * the integrity of the client key store; if omitted, it will not be checked + * @return <code>KeyManager</code>s to be used for creating an + * <code>SSLSocketFactory</code> utilizing the given client key store + * @throws GeneralSecurityException thrown while initializing the + * default <code>KeyManagerFactory</code> + */ + public static KeyManager[] getKeyManagers ( + KeyStore clientKeyStore, + String clientKeyStorePassword) + throws GeneralSecurityException { + + if (clientKeyStore == null) + return null; + + // Now we initialize the default KeyManagerFactory with this KeyStore + String alg=KeyManagerFactory.getDefaultAlgorithm(); + KeyManagerFactory kmFact=KeyManagerFactory.getInstance(alg); + char[] password = null; + if (clientKeyStorePassword != null) + password = clientKeyStorePassword.toCharArray(); + kmFact.init(clientKeyStore, password); + + // And now get the KeyManagers + KeyManager[] kms=kmFact.getKeyManagers(); + return kms; + } + + /** * Initializes an <code>IAIKX509TrustManager</code> for a given trust store, * using configuration data. * @@ -178,7 +242,7 @@ public class SSLUtils { // initialized by the MOA-SP initialization code, in case // MOA-SP is called by API MOAIDTrustManager.initializeLoggingContext(); - IAIKX509TrustManager tm = new MOAIDTrustManager(acceptedServerCertURL); + MOAIDTrustManager tm = new MOAIDTrustManager(acceptedServerCertURL); tm.init(cfg, profile); return new TrustManager[] {tm}; } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/logging/LogMsg.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/logging/LogMsg.java deleted file mode 100644 index 51667f010..000000000 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/logging/LogMsg.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2003 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - */ - - -package at.gv.egovernment.moa.logging; - -/** - * A unified message type to log messages from inside the MOA subsystem. - * - * @author Patrick Peck - * @version $Id$ - */ -public class LogMsg { - /** The message to log. */ - private Object message; - - /** - * Create a <code>LogMsg</code> object. - * - * @param message The actual message to log. May be <code>null</code>. - */ - public LogMsg(Object message) { - this.message = message; - } - - /** - * Convert this log message to a <code>String</code>. - * - * @return The <code>String</code> representation of this log message. - */ - public String toString() { - StringBuffer msg = new StringBuffer(); - LoggingContext ctx = - LoggingContextManager.getInstance().getLoggingContext(); - String tid = ctx != null ? ctx.getTransactionID() : null; - String nodeId = ctx != null ? ctx.getNodeID() : null; - - msg.append("TID="); - msg.append(tid != null ? tid : "<null>"); - msg.append(" NID="); - msg.append(nodeId != null ? nodeId : "<null>"); - msg.append(" MSG="); - msg.append(message != null ? message.toString() : "<null>"); - - return msg.toString(); - } -} diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/logging/LoggingContext.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/logging/LoggingContext.java deleted file mode 100644 index db4b93a0b..000000000 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/logging/LoggingContext.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2003 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - */ - - -package at.gv.egovernment.moa.logging; - -/** - * Encapsulates contextual information (i.e. per request information) for - * logging purposes. - * - * @author Patrick Peck - * @version $Id$ - */ -public class LoggingContext { - /** The name of the node ID system property. */ - public static final String NODE_ID_PROPERTY = "moa.node-id"; - - /** The current transaction ID. */ - private String transactionID; - /** The node ID. */ - private String nodeID; - - /** - * Create a new <code>LoggingContext</code>. - * - * @param transactionID The transaction ID. May be <code>null</code>. - */ - public LoggingContext(String transactionID) { - this.transactionID = transactionID; - this.nodeID = System.getProperty(NODE_ID_PROPERTY); - } - - /** - * Return the transaction ID. - * - * @return The transaction ID. - */ - public String getTransactionID() { - return transactionID; - } - - /** - * Return the node ID. - * - * @return The node ID. - */ - public String getNodeID() { - return nodeID; - } -} diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/logging/LoggingContextManager.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/logging/LoggingContextManager.java deleted file mode 100644 index f0d7b4c07..000000000 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/logging/LoggingContextManager.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2003 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - */ - - -package at.gv.egovernment.moa.logging; - -/** - * Provides each thread with a single instance of <code>LoggingContext</code>. - * - * @author Patrick Peck - * @version $Id$ - */ -public class LoggingContextManager { - /** The single instance of this class. */ - private static LoggingContextManager instance = null; - - /** The <code>LoggingContext</code> for each thread. */ - private ThreadLocal context; - - /** - * Get the single instance of the <code>LoggingContextManager</code> class. - * - * @return LoggingContextManager The single instance. - */ - public static synchronized LoggingContextManager getInstance() { - if (instance == null) { - instance = new LoggingContextManager(); - } - return instance; - } - - /** - * Creates a new <code>LoggingContextManager</code>. - * - * Protected to disallow direct instantiation. - */ - protected LoggingContextManager() { - context = new ThreadLocal(); - } - - /** - * Set the <code>LoggingContext</code> context for the current thread. - * - * @param ctx The <code>LoggingContext</code> for the current thread. - */ - public void setLoggingContext(LoggingContext ctx) { - context.set(ctx); - } - - /** - * Return the <code>LoggingContext</code> for the current thread. - * - * @return LoggingContext The <code>LoggingContext</code> for the current - * thread, or <code>null</code> if none has been set. - */ - public LoggingContext getLoggingContext() { - return (LoggingContext) context.get(); - } - -} diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/Constants.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/Constants.java index 5a5f4edac..260b2ecb1 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/Constants.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/Constants.java @@ -24,7 +24,10 @@ package at.gv.egovernment.moa.util; +import java.util.Collections; import java.util.HashMap; +import java.util.Map; + /** * Contains various constants used throughout the system. @@ -509,6 +512,14 @@ public interface Constants { /** * A map used to map namespace prefixes to namespace URIs */ - public static HashMap<String, String> nSMap = new HashMap<String, String>(5); + public static final Map<String, String> nSMap = Collections.unmodifiableMap(new HashMap<String, String>(){ + private static final long serialVersionUID = 3845384324295136490L; + { + put(Constants.SAML_PREFIX, Constants.SAML_NS_URI); + put(Constants.ECDSA_PREFIX, "http://www.w3.org/2001/04/xmldsig-more#"); + put(Constants.DSIG_PREFIX, Constants.DSIG_NS_URI); + } + }); + } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/MOAEntityResolver.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/MOAEntityResolver.java index 8f3ffd4c6..b1a3f8446 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/MOAEntityResolver.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/MOAEntityResolver.java @@ -31,7 +31,6 @@ import org.apache.xerces.util.URI.MalformedURIException; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; -import at.gv.egovernment.moa.logging.LogMsg; import at.gv.egovernment.moa.logging.Logger; /** @@ -72,7 +71,7 @@ public class MOAEntityResolver implements EntityResolver { if (Logger.isDebugEnabled()) { Logger.debug( - new LogMsg("resolveEntity: p=" + publicId + " s=" + systemId)); + new at.gv.egovernment.moaspss.logging.LogMsg("resolveEntity: p=" + publicId + " s=" + systemId)); } if (publicId != null) { diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/MOAErrorHandler.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/MOAErrorHandler.java index 3769b264d..ea71a677f 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/MOAErrorHandler.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/MOAErrorHandler.java @@ -28,8 +28,8 @@ import org.apache.xml.utils.DefaultErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; -import at.gv.egovernment.moa.logging.LogMsg; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moaspss.logging.LogMsg; /** * An <code>ErrorHandler</code> that logs a message and throws a diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/SSLUtils.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/SSLUtils.java deleted file mode 100644 index c2c67ec58..000000000 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/util/SSLUtils.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright 2003 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - */ - - -package at.gv.egovernment.moa.util; - -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; -import java.security.KeyStore; - -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; - -/** - * Utility for connecting to server applications via SSL. - * - * @author Paul Ivancsics - * @version $Id$ - */ -public class SSLUtils { - - /** - * Creates an <code>SSLSocketFactory</code> which utilizes the given trust store. - * - * @param trustStoreType key store type of trust store - * @param trustStoreInputStream input stream for reading JKS trust store containing - * trusted server certificates; if <code>null</code>, the default - * trust store will be utilized - * @param trustStorePassword if provided, it will be used to check - * the integrity of the trust store; if omitted, it will not be checked - * @return <code>SSLSocketFactory</code> to be used by an <code>HttpsURLConnection</code> - * @throws IOException thrown while reading from the input stream - * @throws GeneralSecurityException thrown while creating the socket factory - */ - public static SSLSocketFactory getSSLSocketFactory( - String trustStoreType, - InputStream trustStoreInputStream, - String trustStorePassword) - throws IOException, GeneralSecurityException { - - TrustManager[] tms = getTrustManagers(trustStoreType, trustStoreInputStream, trustStorePassword); - SSLContext ctx = SSLContext.getInstance("TLS"); - ctx.init(null, tms, null); - - SSLSocketFactory sf = ctx.getSocketFactory(); - return sf; - } - /** - * Creates an <code>SSLSocketFactory</code> which utilizes the - * given trust store and keystore. - * - * @param trustStore trust store containing trusted server certificates; - * if <code>null</code>, the default trust store will be utilized - * @param clientKeyStoreType key store type of <code>clientKeyStore</code> - * @param clientKeyStoreURL URL of key store containing keys to be used for - * client authentication; if <code>null</code>, the default key store will be utilized - * @param clientKeyStorePassword if provided, it will be used to check - * the integrity of the client key store; if omitted, it will not be checked - * @return <code>SSLSocketFactory</code> to be used by an <code>HttpsURLConnection</code> - * @throws IOException thrown while reading key store file - * @throws GeneralSecurityException thrown while creating the socket factory - */ - public static SSLSocketFactory getSSLSocketFactory( - KeyStore trustStore, - String clientKeyStoreType, - String clientKeyStoreURL, - String clientKeyStorePassword) - throws IOException, GeneralSecurityException { - - SSLContext ctx = getSSLContext( - trustStore, clientKeyStoreType, clientKeyStoreURL, clientKeyStorePassword); - SSLSocketFactory sf = ctx.getSocketFactory(); - return sf; - } - /** - * Creates an <code>SSLContext</code> initialized for the - * given trust store and keystore. - * - * @param trustStore trust store containing trusted server certificates; - * if <code>null</code>, the default trust store will be utilized - * @param clientKeyStoreType key store type of <code>clientKeyStore</code> - * @param clientKeyStoreURL URL of key store containing keys to be used for - * client authentication; if <code>null</code>, the default key store will be utilized - * @param clientKeyStorePassword if provided, it will be used to check - * the integrity of the client key store; if omitted, it will not be checked - * @return <code>SSLContext</code> to be used for creating an <code>SSLSocketFactory</code> - * @throws IOException thrown while reading key store file - * @throws GeneralSecurityException thrown while creating the SSL context - */ - public static SSLContext getSSLContext( - KeyStore trustStore, - String clientKeyStoreType, - String clientKeyStoreURL, - String clientKeyStorePassword) - throws IOException, GeneralSecurityException { - - TrustManager[] tms = getTrustManagers(trustStore); - KeyManager[] kms = getKeyManagers(clientKeyStoreType, clientKeyStoreURL, clientKeyStorePassword); - SSLContext ctx = SSLContext.getInstance("TLS"); - ctx.init(kms, tms, null); - return ctx; - } - /** - * Loads the trust store from an input stream and gets the - * <code>TrustManager</code>s from a default <code>TrustManagerFactory</code>, - * initialized from the given trust store. - * @param trustStoreType key store type of trust store - * @param trustStoreInputStream input stream for reading JKS trust store containing - * trusted server certificates; if <code>null</code>, the default - * trust store will be utilized - * @param trustStorePassword if provided, it will be used to check - * the integrity of the trust store; if omitted, it will not be checked - * @return <code>TrustManager</code>s to be used for creating an - * <code>SSLSocketFactory</code> utilizing the given trust store - * @throws IOException thrown while reading from the input stream - * @throws GeneralSecurityException thrown while initializing the - * default <code>TrustManagerFactory</code> - */ - protected static TrustManager[] getTrustManagers( - String trustStoreType, - InputStream trustStoreInputStream, - String trustStorePassword) - throws IOException, GeneralSecurityException { - - if (trustStoreInputStream == null) - return null; - - // Set up the TrustStore to use. We need to load the file into - // a KeyStore instance. - KeyStore trustStore = KeyStoreUtils.loadKeyStore(trustStoreType, trustStoreInputStream, trustStorePassword); - return getTrustManagers(trustStore); - } - /** - * Gets the <code>TrustManager</code>s from a default <code>TrustManagerFactory</code>, - * initialized from the given trust store. - * - * @param trustStore the trust store to use - * @return <code>TrustManager</code>s to be used for creating an - * <code>SSLSocketFactory</code> utilizing the given trust store - * @throws GeneralSecurityException thrown while initializing the - * default <code>TrustManagerFactory</code> - */ - protected static TrustManager[] getTrustManagers(KeyStore trustStore) - throws GeneralSecurityException { - - if (trustStore == null) - return null; - - // Initialize the default TrustManagerFactory with this KeyStore - String alg=TrustManagerFactory.getDefaultAlgorithm(); - TrustManagerFactory tmFact=TrustManagerFactory.getInstance(alg); - tmFact.init(trustStore); - - // And now get the TrustManagers - TrustManager[] tms=tmFact.getTrustManagers(); - return tms; - } - /** - * Loads the client key store from file and gets the - * <code>KeyManager</code>s from a default <code>KeyManagerFactory</code>, - * initialized from the given client key store. - * @param clientKeyStoreType key store type of <code>clientKeyStore</code> - * @param clientKeyStoreURL URL of key store containing keys to be used for - * client authentication; if <code>null</code>, the default key store will be utilized - * @param clientKeyStorePassword password used to check the integrity of the client key store; - * if <code>null</code>, it will not be checked - * @return <code>KeyManager</code>s to be used for creating an - * <code>SSLSocketFactory</code> utilizing the given client key store - * @throws IOException thrown while reading from the key store file - * @throws GeneralSecurityException thrown while initializing the - * default <code>KeyManagerFactory</code> - */ - public static KeyManager[] getKeyManagers ( - String clientKeyStoreType, - String clientKeyStoreURL, - String clientKeyStorePassword) - throws IOException, GeneralSecurityException { - - if (clientKeyStoreURL == null) - return null; - - // Set up the KeyStore to use. We need to load the file into - // a KeyStore instance. - KeyStore clientKeyStore = KeyStoreUtils.loadKeyStore( - clientKeyStoreType, clientKeyStoreURL, clientKeyStorePassword); - return getKeyManagers(clientKeyStore, clientKeyStorePassword); - } - /** - * Gets the <code>KeyManager</code>s from a default <code>KeyManagerFactory</code>, - * initialized from the given client key store. - * @param clientKeyStore client key store - * @param clientKeyStorePassword if provided, it will be used to check - * the integrity of the client key store; if omitted, it will not be checked - * @return <code>KeyManager</code>s to be used for creating an - * <code>SSLSocketFactory</code> utilizing the given client key store - * @throws GeneralSecurityException thrown while initializing the - * default <code>KeyManagerFactory</code> - */ - public static KeyManager[] getKeyManagers ( - KeyStore clientKeyStore, - String clientKeyStorePassword) - throws GeneralSecurityException { - - if (clientKeyStore == null) - return null; - - // Now we initialize the default KeyManagerFactory with this KeyStore - String alg=KeyManagerFactory.getDefaultAlgorithm(); - KeyManagerFactory kmFact=KeyManagerFactory.getInstance(alg); - char[] password = null; - if (clientKeyStorePassword != null) - password = clientKeyStorePassword.toCharArray(); - kmFact.init(clientKeyStore, password); - - // And now get the KeyManagers - KeyManager[] kms=kmFact.getKeyManagers(); - return kms; - } -} diff --git a/id/server/moa-id-commons/src/main/resources/META-INF/persistence.xml b/id/server/moa-id-commons/src/main/resources/META-INF/persistence.xml deleted file mode 100644 index 9bebfa66f..000000000 --- a/id/server/moa-id-commons/src/main/resources/META-INF/persistence.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<persistence xmlns="http://java.sun.com/xml/ns/persistence" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://java.sun.com/xml/ns/persistence -http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" - version="2.0"> - - <persistence-unit name="config" transaction-type="RESOURCE_LOCAL"> - <provider>org.hibernate.ejb.HibernatePersistence</provider> - <class>at.gv.egovernment.moa.id.commons.db.dao.config.ConfigProperty</class> - <!-- <class>at.gv.egovernment.moa.id.commons.db.dao.config.UserDatabase</class> --> - <properties> - </properties> - </persistence-unit> - -</persistence>
\ No newline at end of file diff --git a/id/server/moa-id-commons/src/main/resources/configuration.beans.xml b/id/server/moa-id-commons/src/main/resources/configuration.beans.xml index 4d3caea8c..b97b1c88b 100644 --- a/id/server/moa-id-commons/src/main/resources/configuration.beans.xml +++ b/id/server/moa-id-commons/src/main/resources/configuration.beans.xml @@ -17,6 +17,7 @@ <bean id="moaidconfig" class="at.gv.egovernment.moa.id.commons.config.persistence.MOAIDConfigurationImpl" /> <bean name="config" id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> + <property name="packagesToScan" value="at.gv.egovernment.moa.id.commons.db.dao.config" /> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter" ref="jpaVendorAdapter" /> <property name="persistenceUnitName" value="config" /> diff --git a/id/server/moa-id-commons/src/main/resources/hibernate_moasession.cfg.xml b/id/server/moa-id-commons/src/main/resources/hibernate_moasession.cfg.xml deleted file mode 100644 index e40c8b8a9..000000000 --- a/id/server/moa-id-commons/src/main/resources/hibernate_moasession.cfg.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version='1.0' encoding='utf-8'?> -<!DOCTYPE hibernate-configuration PUBLIC -"-//Hibernate/Hibernate Configuration DTD 3.0//EN" -"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> - -<hibernate-configuration> - <session-factory> - <!-- MOA Session handling mapping files --> - <mapping class="at.gv.egovernment.moa.id.commons.db.dao.session.AssertionStore"/> - <mapping class="at.gv.egovernment.moa.id.commons.db.dao.session.AuthenticatedSessionStore"/> - <mapping class="at.gv.egovernment.moa.id.commons.db.dao.session.OASessionStore"/> - <mapping class="at.gv.egovernment.moa.id.commons.db.dao.session.OldSSOSessionIDStore"/> - <mapping class="at.gv.egovernment.moa.id.commons.db.dao.session.ExceptionStore"/> - </session-factory> -</hibernate-configuration>
\ No newline at end of file diff --git a/id/server/moa-id-commons/src/main/resources/hibernate_statistic.cfg.xml b/id/server/moa-id-commons/src/main/resources/hibernate_statistic.cfg.xml deleted file mode 100644 index aa77a9c67..000000000 --- a/id/server/moa-id-commons/src/main/resources/hibernate_statistic.cfg.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version='1.0' encoding='utf-8'?> -<!DOCTYPE hibernate-configuration PUBLIC -"-//Hibernate/Hibernate Configuration DTD 3.0//EN" -"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> - -<hibernate-configuration> - <session-factory> - <!-- MOA advanced statistic handling mapping files --> - <mapping class="at.gv.egovernment.moa.id.commons.db.dao.statistic.StatisticLog"/> - </session-factory> -</hibernate-configuration>
\ No newline at end of file diff --git a/id/server/moa-id-commons/src/main/resources/statistic.logging.beans.xml b/id/server/moa-id-commons/src/main/resources/statistic.logging.beans.xml new file mode 100644 index 000000000..5f80c6439 --- /dev/null +++ b/id/server/moa-id-commons/src/main/resources/statistic.logging.beans.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans profile="advancedLogOn" + 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:p="http://www.springframework.org/schema/p" + 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></context:annotation-config> + <tx:annotation-driven transaction-manager="statisticLogTransactionManager"/> + + <bean id="statisticLogDataSource" class="org.apache.commons.dbcp2.BasicDataSource" lazy-init="true" destroy-method="close"> + <aop:scoped-proxy/> + <property name="driverClassName" value="${advancedlogging.hibernate.connection.driver_class}" /> + <property name="url" value="${advancedlogging.hibernate.connection.url}"/> + <property name="username" value="${advancedlogging.hibernate.connection.username}" /> + <property name="password" value="${advancedlogging.hibernate.connection.password}" /> + + <property name="connectionProperties" value="${advancedlogging.dbcp.connectionProperties}" /> + <property name="initialSize" value="${advancedlogging.dbcp.initialSize}" /> + <property name="maxTotal" value="${advancedlogging.dbcp.maxActive}" /> + <property name="maxIdle" value="${advancedlogging.dbcp.maxIdle}" /> + <property name="minIdle" value="${advancedlogging.dbcp.minIdle}" /> + <!-- property name="maxWait" value="${moasession.dbcp.maxWaitMillis}" / --> + <property name="testOnBorrow" value="${advancedlogging.dbcp.testOnBorrow}" /> + <property name="testOnReturn" value="${advancedlogging.dbcp.testOnReturn}" /> + <property name="testWhileIdle" value="${advancedlogging.dbcp.testWhileIdle}" /> + <property name="validationQuery" value="${advancedlogging.dbcp.validationQuery}" /> + </bean> + + <bean id="statisticLogSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> + <property name="dataSource" ref="statisticLogDataSource"/> + <property name="packagesToScan" value="at.gv.egovernment.moa.id.commons.db.dao.statistic" /> + <property name="hibernateProperties"> + + <props> + <prop key="hibernate.dialect">${advancedlogging.hibernate.dialect}</prop> + <prop key="hibernate.show_sql">${advancedlogging.hibernate.show_sql}</prop> + <prop key="hibernate.hbm2ddl.auto">${advancedlogging.hibernate.hbm2ddl.auto}</prop> + <prop key="current_session_context_class">${advancedlogging.hibernate.current_session_context_class}</prop> + <prop key="hibernate.transaction.flush_before_completion">${advancedlogging.hibernate.transaction.flush_before_completion}</prop> + <prop key="hibernate.transaction.auto_close_session">${advancedlogging.hibernate.transaction.auto_close_session}</prop> + </props> + </property> + </bean> + + + <bean id="statisticLogDBUtils" class="at.gv.egovernment.moa.id.commons.db.StatisticLogDBUtils"> + </bean> + + <bean name="statisticLogTransactionManager" id="statisticLogTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> + <property name="entityManagerFactory" ref="statistic" /> + </bean> + + <bean id="statisticJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> + <property name="showSql" value="${advancedlogging.hibernate.show_sql}" /> + <property name="generateDdl" value="${advancedlogging.jpaVendorAdapter.generateDdl}" /> + <property name="databasePlatform" value="${advancedlogging.hibernate.dialect}" /> + </bean> + + <bean name="statistic" id="statistic" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> + <property name="dataSource" ref="statisticLogDataSource" /> + <property name="jpaVendorAdapter" ref="statisticJpaVendorAdapter" /> + <property name="packagesToScan" value="at.gv.egovernment.moa.id.commons.db.dao.statistic" /> + <property name="persistenceUnitName" value="statistic" /> + </bean> + + + +</beans>
\ No newline at end of file diff --git a/id/server/moa-id-commons/src/test/java/test/at/gv/egovernment/moa/AllTests.java b/id/server/moa-id-commons/src/test/java/test/at/gv/egovernment/moa/AllTests.java index c0a93bf03..16d1e5adc 100644 --- a/id/server/moa-id-commons/src/test/java/test/at/gv/egovernment/moa/AllTests.java +++ b/id/server/moa-id-commons/src/test/java/test/at/gv/egovernment/moa/AllTests.java @@ -1,56 +1,56 @@ -/* - * Copyright 2003 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - */ - - -package test.at.gv.egovernment.moa; - -import junit.awtui.TestRunner; -import junit.framework.Test; -import junit.framework.TestSuite; - -/** - * @author patrick - * @version $Id$ - */ -public class AllTests { - - public static Test suite() { - TestSuite suite = new TestSuite(); - -// suite.addTestSuite(DOMUtilsTest.class); -// suite.addTestSuite(DateTimeUtilsTest.class); -// suite.addTestSuite(XPathUtilsTest.class); -// suite.addTestSuite(KeyStoreUtilsTest.class); -// suite.addTestSuite(SSLUtilsTest.class); - - return suite; - } - - public static void main(String[] args) { - try { - TestRunner.run(AllTests.class); - } catch (Exception e) { - e.printStackTrace(); - } - } -} +///* +// * Copyright 2003 Federal Chancellery Austria +// * MOA-ID has been developed in a cooperation between BRZ, the Federal +// * Chancellery Austria - ICT staff unit, and Graz University of Technology. +// * +// * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by +// * the European Commission - subsequent versions of the EUPL (the "Licence"); +// * You may not use this work except in compliance with the Licence. +// * You may obtain a copy of the Licence at: +// * http://www.osor.eu/eupl/ +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the Licence is distributed on an "AS IS" basis, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the Licence for the specific language governing permissions and +// * limitations under the Licence. +// * +// * This product combines work with different licenses. See the "NOTICE" text +// * file for details on the various modules and licenses. +// * The "NOTICE" text file is part of the distribution. Any derivative works +// * that you distribute must include a readable copy of the "NOTICE" text file. +// */ +// +// +//package test.at.gv.egovernment.moa; +// +//import junit.awtui.TestRunner; +//import junit.framework.Test; +//import junit.framework.TestSuite; +// +///** +// * @author patrick +// * @version $Id$ +// */ +//public class AllTests { +// +// public static Test suite() { +// TestSuite suite = new TestSuite(); +// +//// suite.addTestSuite(DOMUtilsTest.class); +//// suite.addTestSuite(DateTimeUtilsTest.class); +//// suite.addTestSuite(XPathUtilsTest.class); +//// suite.addTestSuite(KeyStoreUtilsTest.class); +//// suite.addTestSuite(SSLUtilsTest.class); +// +// return suite; +// } +// +// public static void main(String[] args) { +// try { +// TestRunner.run(AllTests.class); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +//} diff --git a/id/server/moa-id-commons/src/test/java/test/at/gv/egovernment/moa/util/SSLUtilsTest.java b/id/server/moa-id-commons/src/test/java/test/at/gv/egovernment/moa/util/SSLUtilsTest.java deleted file mode 100644 index 2b5094fb8..000000000 --- a/id/server/moa-id-commons/src/test/java/test/at/gv/egovernment/moa/util/SSLUtilsTest.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright 2003 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - */ - - -package test.at.gv.egovernment.moa.util; - -import java.net.URL; -import java.security.KeyStore; -import java.security.Security; - -import javax.net.ssl.SSLException; -import javax.net.ssl.SSLSocketFactory; - -import junit.framework.TestCase; -import at.gv.egovernment.moa.util.KeyStoreUtils; -import at.gv.egovernment.moa.util.SSLUtils; - -import com.sun.net.ssl.HostnameVerifier; -import com.sun.net.ssl.HttpsURLConnection; - -/** - * @author Paul Ivancsics - * @version $Id$ - */ -public class SSLUtilsTest extends TestCase { - - public SSLUtilsTest(String arg0) { - super(arg0); - } - - - protected void setUp() throws Exception { - //System.setProperty("javax.net.debug", "all"); - Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); - System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol"); - System.setProperty("https.cipherSuites", "SSL_DHE_DSS_WITH_DES_CBC_SHA,SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,SSL_RSA_WITH_DES_CBC_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_RSA_EXPORT_WITH_RC4_40_MD5"); - } - - public void testGetSSLSocketFactoryBaltimoreOK() throws Exception { - doTestGetSSLSocketFactory( - "GET", - "https://www.baltimore.com/", - false, - "file:data/test/security/cacerts+gt_cybertrust_root", - "changeit", - true); - } - public void testGetSSLSocketFactoryBaltimoreNOK() throws Exception { - doTestGetSSLSocketFactory( - "GET", - "https://www.baltimore.com/", - false, - "file:data/test/security/cacerts", - "changeit", - false); - } - public void testGetSSLSocketFactoryVerisignOK() throws Exception { - doTestGetSSLSocketFactory( - "GET", - "https://www.verisign.com/", - false, - "file:data/test/security/cacerts", - "changeit", - true); - } - public void testGetSSLSocketFactoryVerisignNoTruststoreOK() throws Exception { - doTestGetSSLSocketFactory( - "GET", - "https://www.verisign.com/", - false, - null, - null, - true); - } - public void testGetSSLSocketFactoryLocalhostOK() throws Exception { - String urlString = "https://localhost:8443/moa-id-auth/index.jsp"; - doTestGetSSLSocketFactory( - "GET", - urlString, - true, - "file:data/test/security/server.keystore.tomcat", - "changeit", - true); - } - public void testGetSSLSocketFactoryLocalhostNOK() throws Exception { - String urlString = "https://localhost:8443/moa-id-auth/index.jsp"; - doTestGetSSLSocketFactory( - "GET", - urlString, - true, - null, - null, - false); - } - - public void doTestGetSSLSocketFactory( - String requestMethod, - String urlString, - boolean useHostnameVerifierHack, - String truststoreurl, - String trustpassword, - boolean shouldOk - ) throws Exception { - - doTestGetSSLSocketFactory( - requestMethod, urlString, useHostnameVerifierHack, truststoreurl, trustpassword, null, null, null, shouldOk); - } - public void doTestGetSSLSocketFactory( - String requestMethod, - String urlString, - boolean useHostnameVerifierHack, - String truststoreurl, - String trustpassword, - String keystoretype, - String keystoreurl, - String keypassword, - boolean shouldOk - ) throws Exception { - - KeyStore truststore = null; - if (truststoreurl != null) - truststore = KeyStoreUtils.loadKeyStore("jks", truststoreurl, trustpassword); - SSLSocketFactory sf = SSLUtils.getSSLSocketFactory( - truststore, keystoretype, keystoreurl, keypassword); - System.out.println(requestMethod + " " + urlString); - - URL url = new URL(urlString); - HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); - conn.setRequestMethod(requestMethod); - conn.setDoInput(true); - conn.setDoOutput(true); - conn.setUseCaches(false); - conn.setAllowUserInteraction(false); - conn.setSSLSocketFactory(sf); - if (useHostnameVerifierHack) - conn.setHostnameVerifier(new HostnameVerifierHack()); - try { - conn.connect(); - assertTrue(shouldOk); - assertEquals(200, conn.getResponseCode()); - conn.disconnect(); - } - catch (SSLException ex) { - assertFalse(shouldOk); - } - } -// private byte[] readTruststore(String filename) throws IOException { -// if (filename == null) -// return null; -// FileInputStream in = new FileInputStream(filename); -// byte[] buffer = new byte[in.available()]; -// in.read(buffer); -// in.close(); -// return buffer; -// } - private class HostnameVerifierHack implements HostnameVerifier { - public boolean verify(String arg0, String arg1) { - return true; - } - } -} diff --git a/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAContextCloseHandler.java b/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAContextCloseHandler.java new file mode 100644 index 000000000..f99013082 --- /dev/null +++ b/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAContextCloseHandler.java @@ -0,0 +1,166 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth; + +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.TimeUnit; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextClosedEvent; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.stereotype.Component; + +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + */ +@Component +public class MOAContextCloseHandler implements ApplicationListener<ContextClosedEvent>, ApplicationContextAware, BeanPostProcessor { + + private ApplicationContext context; + + /* (non-Javadoc) + * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent) + */ + @Override + public void onApplicationEvent(ContextClosedEvent arg0) { + Logger.info("MOA-ID-Auth shutdown process started ..."); + + try { + Logger.debug("CleanUp objects with implements the IDestroyable interface ... "); + Map<String, IDestroyableObject> objectsToDestroy = context.getBeansOfType(IDestroyableObject.class); + if (objectsToDestroy != null) { + Iterator<Entry<String, IDestroyableObject>> interator = + objectsToDestroy.entrySet().iterator(); + while (interator.hasNext()) { + Entry<String, IDestroyableObject> object = interator.next(); + try { + object.getValue().fullyDestroy(); + Logger.debug("Object with ID:" + object.getKey() + " is destroyed"); + + } catch (Exception e) { + Logger.warn("Destroing object with ID:" + object.getKey() + " FAILED!", e); + + } + } + } + Logger.info("Object cleanUp complete"); + + Logger.debug("Stopping Spring Thread-Pools ... "); + //shut-down task schedulers + Map<String, ThreadPoolTaskScheduler> schedulers = context.getBeansOfType(ThreadPoolTaskScheduler.class); + for (ThreadPoolTaskScheduler scheduler : schedulers.values()) { + scheduler.getScheduledExecutor().shutdown(); + try { + scheduler.getScheduledExecutor().awaitTermination(20000, TimeUnit.MILLISECONDS); + if(scheduler.getScheduledExecutor().isTerminated() || scheduler.getScheduledExecutor().isShutdown()) + Logger.debug("Scheduler "+scheduler.getThreadNamePrefix() + " has stoped"); + else{ + Logger.debug("Scheduler "+scheduler.getThreadNamePrefix() + " has not stoped normally and will be shut down immediately"); + scheduler.getScheduledExecutor().shutdownNow(); + Logger.info("Scheduler "+scheduler.getThreadNamePrefix() + " has shut down immediately"); + } + } catch (IllegalStateException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + + } finally { + scheduler.shutdown(); + + } + } + + //shut-down task executors + Map<String, ThreadPoolTaskExecutor> executers = context.getBeansOfType(ThreadPoolTaskExecutor.class); + for (ThreadPoolTaskExecutor executor: executers.values()) { + int retryCount = 0; + while(executor.getActiveCount()>0 && ++retryCount<51){ + try { + Logger.debug("Executer "+executor.getThreadNamePrefix()+" is still working with active " + executor.getActiveCount()+" work. Retry count is "+retryCount); + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if(!(retryCount<51)) + Logger.debug("Executer "+executor.getThreadNamePrefix()+" is still working.Since Retry count exceeded max value "+retryCount+", will be killed immediately"); + executor.shutdown(); + Logger.debug("Executer "+executor.getThreadNamePrefix()+" with active " + executor.getActiveCount()+" work has killed"); + } + + Logger.debug("Spring Thread-Pools stopped"); + + Logger.info("MOA-ID-Auth shutdown process finished"); + + } catch (Exception e) { + Logger.warn("MOA-ID-Auth shutdown process has an error.", e); + + } + + //System.exit(0); + //Thread.currentThread().interrupt(); + + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) + */ + @Override + public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException { + if(arg0 instanceof ThreadPoolTaskScheduler) + ((ThreadPoolTaskScheduler)arg0).setWaitForTasksToCompleteOnShutdown(true); + if(arg0 instanceof ThreadPoolTaskExecutor) + ((ThreadPoolTaskExecutor)arg0).setWaitForTasksToCompleteOnShutdown(true); + return arg0; + + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String) + */ + @Override + public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException { + return arg0; + + } + + /* (non-Javadoc) + * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) + */ + @Override + public void setApplicationContext(ApplicationContext arg0) throws BeansException { + this.context = arg0; + + } + +} diff --git a/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthSpringInitializer.java b/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthSpringInitializer.java index 327d659ec..bfb43e61f 100644 --- a/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthSpringInitializer.java +++ b/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthSpringInitializer.java @@ -7,6 +7,8 @@ import javax.servlet.ServletRegistration; 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; @@ -18,6 +20,7 @@ import org.springframework.web.servlet.DispatcherServlet; import at.gv.egiz.components.spring.api.SpringLoader; import at.gv.egovernment.moa.id.commons.utils.MOAIDMessageProvider; +import at.gv.egovernment.moa.id.config.auth.PropertyBasedAuthConfigurationProvider; import at.gv.egovernment.moa.logging.Logger; /** @@ -50,16 +53,34 @@ public class MOAIDAuthSpringInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { try { + Logger.info("=============== Loading Config Root Context! ==============="); + ApplicationContext cfgRootContext = + new ClassPathXmlApplicationContext(new String[] { + "/moaid.configuration.beans.xml", + "/configuration.beans.xml"}); + + Logger.info("=============== Loading Root Context! ==============="); GenericWebApplicationContext rootContext = new GenericWebApplicationContext(); rootContext.setServletContext(servletContext); + rootContext.setParent(cfgRootContext); + PropertyBasedAuthConfigurationProvider moaidconfig = (PropertyBasedAuthConfigurationProvider) cfgRootContext.getBean("moaidauthconfig"); + String[] springProfiles = moaidconfig.getActiveProfiles(); + + Logger.info("=============== Setting active profiles! ==============="); if (this.activeProfiles != null) { for (String profile : this.activeProfiles) { rootContext.getEnvironment().addActiveProfile(profile); } } + + if (springProfiles != null) { + for (String profile : springProfiles) { + rootContext.getEnvironment().addActiveProfile(profile); + } + } Logger.info("=============== Loading Local Contexts! ==============="); XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader( @@ -76,7 +97,7 @@ public class MOAIDAuthSpringInitializer implements WebApplicationInitializer { // logger.debug("Beans after logAMQP in {}", rootContext); // dumpBeanDefinitions(rootContext); - + Logger.info("=============== Loading SPI Context! ==============="); // logger.debug("Startup with context {}", rootContext); if (rootContext instanceof BeanDefinitionRegistry) { diff --git a/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthSpringResourceProvider.java b/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthSpringResourceProvider.java index def32e144..565e1cccd 100644 --- a/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthSpringResourceProvider.java +++ b/id/server/moa-id-spring-initializer/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthSpringResourceProvider.java @@ -38,11 +38,12 @@ public class MOAIDAuthSpringResourceProvider implements SpringResourceProvider { */ @Override public Resource[] getResourcesToLoad() { - ClassPathResource moaidauthConfig = new ClassPathResource("/moaid.configuration.beans.xml", MOAIDAuthInitializer.class); - ClassPathResource configurationDBConfig = new ClassPathResource("/configuration.beans.xml", MOAIDAuthInitializer.class); - ClassPathResource moaIdAuthBeans = new ClassPathResource("/moaid.authentication.beans.xml", MOAIDAuthInitializer.class); - - return new Resource[] {configurationDBConfig, moaidauthConfig, moaIdAuthBeans}; + ClassPathResource moaIdAuthBeans = new ClassPathResource("/moaid.authentication.beans.xml", MOAIDAuthInitializer.class); + ClassPathResource moaSessionCommonBeans = new ClassPathResource("/session.common.beans.xml", MOAIDAuthInitializer.class); + ClassPathResource moaSessionDBBeans = new ClassPathResource("/session.db.beans.xml", MOAIDAuthInitializer.class); + ClassPathResource moaSessionRedisBeans = new ClassPathResource("/session.redis.beans.xml", MOAIDAuthInitializer.class); + ClassPathResource configurationStatisticLog = new ClassPathResource("/statistic.logging.beans.xml", MOAIDAuthInitializer.class); + return new Resource[] {configurationStatisticLog, moaIdAuthBeans, moaSessionDBBeans, moaSessionRedisBeans, moaSessionCommonBeans}; } diff --git a/id/server/moa-id-spring-initializer/src/main/resources/applicationContext.xml b/id/server/moa-id-spring-initializer/src/main/resources/applicationContext.xml index ae38c836e..2c53d55b9 100644 --- a/id/server/moa-id-spring-initializer/src/main/resources/applicationContext.xml +++ b/id/server/moa-id-spring-initializer/src/main/resources/applicationContext.xml @@ -27,5 +27,8 @@ <bean class="at.gv.egovernment.moa.id.auth.servlet.interceptor.UniqueSessionIdentifierInterceptor" /> </mvc:interceptors> + <bean id="MOAIDContextCloseHandler" + class="at.gv.egovernment.moa.id.auth.MOAContextCloseHandler"/> + </beans> diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/pom.xml b/id/server/modules/moa-id-modul-citizencard_authentication/pom.xml index f2403a62e..e5b38f9b6 100644 --- a/id/server/modules/moa-id-modul-citizencard_authentication/pom.xml +++ b/id/server/modules/moa-id-modul-citizencard_authentication/pom.xml @@ -23,6 +23,13 @@ </dependency> <dependency> + <groupId>iaik.prod</groupId> + <artifactId>iaik_ixsil</artifactId> + <version>1.2.2.5</version> + <scope>test</scope> + </dependency> + + <dependency> <groupId>MOA.id.server</groupId> <artifactId>moa-id-commons</artifactId> <type>test-jar</type> diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java index f5000581c..90ed1c886 100644 --- a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java @@ -65,7 +65,6 @@ import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.data.MISMandate; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; import at.gv.egovernment.moa.id.util.XMLUtil; -import at.gv.egovernment.moa.logging.LogMsg; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.Constants; import at.gv.egovernment.moa.util.DOMUtils; @@ -73,6 +72,7 @@ import at.gv.egovernment.moa.util.DateTimeUtils; import at.gv.egovernment.moa.util.FileUtils; import at.gv.egovernment.moa.util.MiscUtil; import at.gv.egovernment.moa.util.StringUtils; +import at.gv.egovernment.moaspss.logging.LogMsg; import iaik.asn1.ObjectID; import iaik.x509.X509Certificate; import iaik.x509.X509ExtensionInitException; diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java index df101f5b7..4e591ada2 100644 --- a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java @@ -46,13 +46,6 @@ package at.gv.egovernment.moa.id.auth.validator; -import iaik.asn1.ObjectID; -import iaik.asn1.structures.Name; -import iaik.security.ecc.ecdsa.ECPublicKey; -import iaik.utils.RFC2253NameParserException; -import iaik.x509.X509Certificate; -import iaik.x509.X509ExtensionInitException; - import java.security.InvalidKeyException; import java.security.PublicKey; import java.security.interfaces.RSAPublicKey; @@ -70,6 +63,11 @@ import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.utils.MOAIDMessageProvider; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.logging.Logger; +import iaik.asn1.structures.Name; +import iaik.security.ec.common.ECPublicKey; +import iaik.utils.RFC2253NameParserException; +import iaik.x509.X509Certificate; +import iaik.x509.X509ExtensionInitException; /** * This class is used to validate an {@link VerifyXMLSignatureResponse} @@ -268,9 +266,9 @@ public class VerifyXMLSignatureResponseValidator { //compare ECDSAPublicKeys if( ( (idl.getPublicKey()[i] instanceof java.security.interfaces.ECPublicKey) || - (idl.getPublicKey()[i] instanceof iaik.security.ecc.ecdsa.ECPublicKey)) && + (idl.getPublicKey()[i] instanceof ECPublicKey)) && ( (pubKeySignature instanceof java.security.interfaces.ECPublicKey) || - (pubKeySignature instanceof iaik.security.ecc.ecdsa.ECPublicKey) ) ) { + (pubKeySignature instanceof ECPublicKey) ) ) { try { ECPublicKey ecdsaPubKeySignature = new ECPublicKey(pubKeySignature.getEncoded()); diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java index 7b5a7b9c0..12e58342a 100644 --- a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java @@ -152,11 +152,11 @@ public class MISSimpleClient { } return foundMandates; } catch (ParserConfigurationException e) { - throw new MISSimpleClientException("service.06", e); + throw new MISSimpleClientException("service.06", new Object[]{e.getMessage()}, e); } catch (DOMException e) { - throw new MISSimpleClientException("service.06", e); + throw new MISSimpleClientException("service.06", new Object[]{e.getMessage()}, e); } catch (TransformerException e) { - throw new MISSimpleClientException("service.06", e); + throw new MISSimpleClientException("service.06", new Object[]{e.getMessage()}, e); } } @@ -259,11 +259,11 @@ public class MISSimpleClient { return msid; } catch (ParserConfigurationException e) { - throw new MISSimpleClientException("service.06", e); + throw new MISSimpleClientException("service.06", new Object[]{e.getMessage()}, e); } catch (DOMException e) { - throw new MISSimpleClientException("service.06", e); + throw new MISSimpleClientException("service.06", new Object[]{e.getMessage()}, e); } catch (TransformerException e) { - throw new MISSimpleClientException("service.06", e); + throw new MISSimpleClientException("service.06", new Object[]{e.getMessage()}, e); } } @@ -315,19 +315,19 @@ public class MISSimpleClient { return unpackFromSOAP(doc.getDocumentElement()); } catch(IOException e) { - throw new MISSimpleClientException("service.04", e); + throw new MISSimpleClientException("service.04", new Object[]{webServiceURL, e.getMessage()}, e); } catch (TransformerException e) { - throw new MISSimpleClientException("service.06", e); + throw new MISSimpleClientException("service.06", new Object[]{e.getMessage()}, e); } catch (SAXException e) { - throw new MISSimpleClientException("service.06", e); + throw new MISSimpleClientException("service.06", new Object[]{e.getMessage()}, e); } catch (ParserConfigurationException e) { - throw new MISSimpleClientException("service.06", e); + throw new MISSimpleClientException("service.06", new Object[]{e.getMessage()}, e); } catch (Exception e) { - throw new MISSimpleClientException("service.06", e); + throw new MISSimpleClientException("service.06", new Object[]{e.getMessage()}, e); } diff --git a/id/server/modules/moa-id-module-eIDAS/pom.xml b/id/server/modules/moa-id-module-eIDAS/pom.xml index addf086d8..174ce40cb 100644 --- a/id/server/modules/moa-id-module-eIDAS/pom.xml +++ b/id/server/modules/moa-id-module-eIDAS/pom.xml @@ -12,10 +12,11 @@ <properties> <repositoryPath>${basedir}/../../../../repository</repositoryPath> - <eidas-commons.version>eidas.1.0</eidas-commons.version> - <eidas-saml-engine.version>eidas.1.0</eidas-saml-engine.version> - <eidas-encryption.version>eidas.1.0</eidas-encryption.version> - <eidas-configmodule.version>eidas.1.0</eidas-configmodule.version> + <eidas-commons.version>1.1.0</eidas-commons.version> + <eidas-light-commons.version>1.1.0</eidas-light-commons.version> + <eidas-saml-engine.version>1.1.0</eidas-saml-engine.version> + <eidas-encryption.version>1.1.0</eidas-encryption.version> + <eidas-configmodule.version>1.1.0</eidas-configmodule.version> </properties> @@ -44,6 +45,11 @@ <dependencies> <dependency> + <groupId>MOA.id.server</groupId> + <artifactId>moa-id-lib</artifactId> + </dependency> + + <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <scope>test</scope> @@ -75,6 +81,12 @@ <dependency> <groupId>eu.eidas</groupId> + <artifactId>eidas-light-commons</artifactId> + <version>${eidas-light-commons.version}</version> + </dependency> + + <dependency> + <groupId>eu.eidas</groupId> <artifactId>eidas-configmodule</artifactId> <version>${eidas-configmodule.version}</version> <exclusions> @@ -100,7 +112,7 @@ <!-- eidas SAML Engine --> <dependency> <groupId>eu.eidas</groupId> - <artifactId>saml-engine</artifactId> + <artifactId>eidas-saml-engine</artifactId> <version>${eidas-saml-engine.version}</version> <scope>compile</scope> <exclusions> diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java index d93d739b1..f45b6ffa5 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java @@ -22,15 +22,12 @@ */ package at.gv.egovernment.moa.id.auth.modules.eidas; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - import org.opensaml.xml.encryption.EncryptionConstants; import org.opensaml.xml.signature.SignatureConstants; +//import eu.eidas.auth.engine.core.validator.eidas.EIDASAttributes; -import eu.eidas.auth.engine.core.eidas.EidasAttributesTypes; -import eu.eidas.auth.engine.core.validator.eidas.EIDASAttributes; +import eu.eidas.auth.commons.attribute.AttributeRegistries; +import eu.eidas.auth.commons.attribute.AttributeRegistry; /** * @author tlenz @@ -54,6 +51,7 @@ public class Constants { //configuration property keys public static final String CONIG_PROPS_EIDAS_PREFIX="moa.id.protocols.eIDAS"; public static final String CONIG_PROPS_EIDAS_SAMLENGINE="samlengine"; + public static final String CONIG_PROPS_EIDAS_NODE= CONIG_PROPS_EIDAS_PREFIX + ".node"; public static final String CONIG_PROPS_EIDAS_SAMLENGINE_PREFIX=CONIG_PROPS_EIDAS_PREFIX + "." + CONIG_PROPS_EIDAS_SAMLENGINE; public static final String CONIG_PROPS_EIDAS_SAMLENGINE_BASIC_CONFIGFILE = CONIG_PROPS_EIDAS_SAMLENGINE_PREFIX + ".config.file"; public static final String CONIG_PROPS_EIDAS_SAMLENGINE_SIGN="sign"; @@ -64,23 +62,33 @@ public class Constants { + CONIG_PROPS_EIDAS_SAMLENGINE_ENCRYPT + ".config.file"; public static final String CONIG_PROPS_EIDAS_METADATA_VALIDATION_TRUSTSTORE = CONIG_PROPS_EIDAS_PREFIX + ".metadata.validation.truststore"; + public static final String CONIG_PROPS_EIDAS_NODE_COUNTRYCODE = CONIG_PROPS_EIDAS_NODE + ".countrycode"; + public static final String CONIG_PROPS_EIDAS_NODE_COUNTRY = CONIG_PROPS_EIDAS_NODE + ".country"; + public static final String CONIG_PROPS_EIDAS_NODE_LoA = CONIG_PROPS_EIDAS_NODE + ".LoA"; + + //timeouts and clock skews - public static final long CONFIG_PROPS_SKEWTIME = 2 * 60 * 1000; //2 minutes skew time for response validation + public static final int CONFIG_PROPS_SKEWTIME = 2 * 60 * 1000; //2 minutes skew time for response validation public static final int CONFIG_PROPS_METADATA_SOCKED_TIMEOUT = 20 * 1000; //20 seconds metadata socked timeout public static final long CONFIG_PROPS_METADATA_GARBAGE_TIMEOUT = 7 * 24 * 60 * 60 * 1000; //remove unused eIDAS metadata after 7 days - - //eIDAS attribute names - public static final String eIDAS_ATTR_PERSONALIDENTIFIER = EIDASAttributes.ATTRIBUTE_NAME_SUFFIX_PERSONIDENTIFIER; - public static final String eIDAS_ATTR_DATEOFBIRTH = EIDASAttributes.ATTRIBUTE_NAME_SUFFIX_DATEOFBIRTH; - public static final String eIDAS_ATTR_CURRENTGIVENNAME = EIDASAttributes.ATTRIBUTE_NAME_SUFFIX_FIRSTNAME; - public static final String eIDAS_ATTR_CURRENTFAMILYNAME = EIDASAttributes.ATTRIBUTE_NAME_SUFFIX_GIVENNAME; + + //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"; //http endpoint descriptions public static final String eIDAS_HTTP_ENDPOINT_SP_POST = "/eidas/sp/post"; public static final String eIDAS_HTTP_ENDPOINT_SP_REDIRECT = "/eidas/sp/redirect"; - public static final String eIDAS_HTTP_ENDPOINT_IDP_POST = "/eidas/idp/post"; + //public static final String eIDAS_HTTP_ENDPOINT_IDP_POST = "/eidas/idp/post"; + //public static final String eIDAS_HTTP_ENDPOINT_IDP_REDIRECT = "/eidas/idp/redirect"; public static final String eIDAS_HTTP_ENDPOINT_IDP_COLLEAGUEREQUEST = "/eidas/ColleagueRequest"; - public static final String eIDAS_HTTP_ENDPOINT_IDP_REDIRECT = "/eidas/idp/redirect"; public static final String eIDAS_HTTP_ENDPOINT_METADATA = "/eidas/metadata"; @@ -92,22 +100,38 @@ public class Constants { public static final int eIDAS_REVERSIONSLOG_SP_AUTHRESPONSE= 3404; //metadata constants - public final static Map<String, EidasAttributesTypes> METADATA_POSSIBLE_ATTRIBUTES = Collections.unmodifiableMap( - new HashMap<String, EidasAttributesTypes>(){ - private static final long serialVersionUID = 1L; - { - put(EIDASAttributes.ATTRIBUTE_GIVENNAME, EidasAttributesTypes.NATURAL_PERSON_MANDATORY); - put(EIDASAttributes.ATTRIBUTE_FIRSTNAME, EidasAttributesTypes.NATURAL_PERSON_MANDATORY); - put(EIDASAttributes.ATTRIBUTE_DATEOFBIRTH, EidasAttributesTypes.NATURAL_PERSON_MANDATORY); - put(EIDASAttributes.ATTRIBUTE_PERSONIDENTIFIER, EidasAttributesTypes.NATURAL_PERSON_MANDATORY); - - //TODO: add additional attributes for eIDAS with mandates - //put(EIDASAttributes.ATTRIBUTE_LEGALIDENTIFIER, EidasAttributesTypes.LEGAL_PERSON_MANDATORY); - //put(EIDASAttributes.ATTRIBUTE_LEGALNAME, EidasAttributesTypes.LEGAL_PERSON_MANDATORY); - } - } - ); +// public final static Map<String, EidasAttributesTypes> METADATA_POSSIBLE_ATTRIBUTES = Collections.unmodifiableMap( +// new HashMap<String, EidasAttributesTypes>(){ +// private static final long serialVersionUID = 1L; +// { +// put(EIDASAttributes.ATTRIBUTE_GIVENNAME, EidasAttributesTypes.NATURAL_PERSON_MANDATORY); +// put(EIDASAttributes.ATTRIBUTE_FIRSTNAME, EidasAttributesTypes.NATURAL_PERSON_MANDATORY); +// put(EIDASAttributes.ATTRIBUTE_DATEOFBIRTH, EidasAttributesTypes.NATURAL_PERSON_MANDATORY); +// put(EIDASAttributes.ATTRIBUTE_PERSONIDENTIFIER, EidasAttributesTypes.NATURAL_PERSON_MANDATORY); +// +// //TODO: add additional attributes for eIDAS with mandates +// //put(EIDASAttributes.ATTRIBUTE_LEGALIDENTIFIER, EidasAttributesTypes.LEGAL_PERSON_MANDATORY); +// //put(EIDASAttributes.ATTRIBUTE_LEGALNAME, EidasAttributesTypes.LEGAL_PERSON_MANDATORY); +// } +// } +// ); + public static final AttributeRegistry NAT_ATTR = + AttributeRegistries.of( eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.PERSON_IDENTIFIER, + eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_FAMILY_NAME, + eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_GIVEN_NAME, + eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.DATE_OF_BIRTH + ); + + public static final AttributeRegistry LEGAL_ATTR = + AttributeRegistries.of( eu.eidas.auth.engine.core.eidas.spec.LegalPersonSpec.Definitions.LEGAL_PERSON_IDENTIFIER, + eu.eidas.auth.engine.core.eidas.spec.LegalPersonSpec.Definitions.LEGAL_NAME + ); + + public static final AttributeRegistry MOA_IDP_ATTR_REGISTRY = + AttributeRegistries.copyOf(NAT_ATTR, LEGAL_ATTR); + + public static final String METADATA_ALLOWED_ALG_DIGIST = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256 + ";" + SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512 ; diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOASWSigner.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOASWSigner.java new file mode 100644 index 000000000..302c12aaa --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOASWSigner.java @@ -0,0 +1,56 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.eidas.config; + +import java.util.Map; + +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import eu.eidas.auth.engine.configuration.SamlEngineConfigurationException; +import eu.eidas.auth.engine.configuration.dom.ConfigurationAdapter; +import eu.eidas.auth.engine.configuration.dom.ConfigurationKey; +import eu.eidas.auth.engine.core.impl.KeyStoreProtocolSigner; +import eu.eidas.samlengineconfig.CertificateConfigurationManager; + +/** + * @author tlenz + * + */ +public class MOASWSigner extends KeyStoreProtocolSigner { + + public MOASWSigner(Map<String, String> properties) throws SamlEngineConfigurationException { + super(properties); + + } + + /** + * @param configManager + * @throws SamlEngineConfigurationException + */ + public MOASWSigner(CertificateConfigurationManager configManager) throws SamlEngineConfigurationException { + super(ConfigurationAdapter.adapt(configManager).getInstances().get(Constants.eIDAS_SAML_ENGINE_NAME).getConfigurationEntries().get(ConfigurationKey.SIGNATURE_CONFIGURATION.getKey()).getParameters()); + + } + + + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLEngineConfigurationImpl.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLEngineConfigurationImpl.java index 5d1874157..78793d3fc 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLEngineConfigurationImpl.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLEngineConfigurationImpl.java @@ -42,9 +42,7 @@ import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.FileUtils; import at.gv.egovernment.moa.util.MiscUtil; - import eu.eidas.samlengineconfig.BinaryParameter; -import eu.eidas.samlengineconfig.ConfigurationParameter; import eu.eidas.samlengineconfig.EngineInstance; import eu.eidas.samlengineconfig.InstanceConfiguration; import eu.eidas.samlengineconfig.PropsParameter; @@ -57,10 +55,10 @@ import eu.eidas.samlengineconfig.SamlEngineConfiguration; public class MOAeIDASSAMLEngineConfigurationImpl extends SamlEngineConfiguration { - private static final String KEYSTORE_PATH="keystorePath"; - private static final String METADATA_KEYSTORE_PATH="metadata.keystorePath"; + private static final String KEYSTORE_PATH="keyStorePath"; + private static final String METADATA_KEYSTORE_PATH="metadata.keyStorePath"; private static final String ENCRYPTION_ACTIVATION="encryptionActivation"; - private static final String[] BINARY_PARAMETERS={KEYSTORE_PATH, ENCRYPTION_ACTIVATION,METADATA_KEYSTORE_PATH}; + public static final String[] BINARY_PARAMETERS={KEYSTORE_PATH, ENCRYPTION_ACTIVATION,METADATA_KEYSTORE_PATH}; public List<EngineInstance> getInstances(){ return super.getInstances(); @@ -95,7 +93,7 @@ public class MOAeIDASSAMLEngineConfigurationImpl extends //add basic eIDAS SAML-engine configuration MOAeIDASSAMLInstanceConfigurationImpl samlBaseConfig = new MOAeIDASSAMLInstanceConfigurationImpl(); samlBaseConfig.setName(Constants.eIDAS_SAML_ENGINE_NAME_ID_BASICCONFIG); - samlBaseConfig.addParameter(loadConfigurationFromExternalFile(Constants.CONIG_PROPS_EIDAS_SAMLENGINE_BASIC_CONFIGFILE)); + samlBaseConfig.addParameter(buildPropsParameter(Constants.CONIG_PROPS_EIDAS_SAMLENGINE_BASIC_CONFIGFILE)); engineConfigs.add(samlBaseConfig); //add signing eIDAS SAML-engine configuration @@ -103,7 +101,7 @@ public class MOAeIDASSAMLEngineConfigurationImpl extends samlSignConfig.setName(Constants.eIDAS_SAML_ENGINE_NAME_ID_SIGNATURECONFIG); samlSignConfig.addParameter(Constants.eIDAS_SAML_ENGINE_NAME_ID_CLASS, Constants.SAML_SIGNING_IMPLENTATION); - + //TODO: load signing keys directly from MOA-ID configuration in finale version samlSignConfig.addParameter(loadConfigurationFromExternalFile(Constants.CONIG_PROPS_EIDAS_SAMLENGINE_SIGN_CONFIGFILE)); engineConfigs.add(samlSignConfig); @@ -122,16 +120,16 @@ public class MOAeIDASSAMLEngineConfigurationImpl extends super.addInstance(engineInst); } - + /** * Load an external eIDAS SAML-engine configuration file, which is referenced from MOA-ID configuration * * @param key Configuration key, which is used in property based MOA-ID configuration file - * @return eIDAS SAML-engine configuration object + * @return eIDAS SAML-engine configuration Properties * @throws ConfigurationException */ - private ConfigurationParameter loadConfigurationFromExternalFile(String key) throws ConfigurationException { + private Properties loadConfigurationFromExternalFile(String key) throws ConfigurationException { String configFile = AuthConfigurationProviderFactory.getInstance().getBasicMOAIDConfiguration(key); if (MiscUtil.isEmpty(configFile)) { @@ -141,15 +139,21 @@ public class MOAeIDASSAMLEngineConfigurationImpl extends return null; } - Properties inputProps = loadPropsFromXml(configFile); - return buildPropsParameter(inputProps, configFile); + Properties inputProps = loadPropsFromXml(configFile); + return inputProps; + //return buildPropsParameter(inputProps, configFile); } - private PropsParameter buildPropsParameter(Properties inputProps, String fileName) throws EIDASEngineConfigurationException { + private PropsParameter buildPropsParameter(String configKey) throws ConfigurationException { + Properties inputProps = loadConfigurationFromExternalFile(configKey); + + String configFile = + AuthConfigurationProviderFactory.getInstance().getBasicMOAIDConfiguration(configKey); + PropsParameter outputProps = new PropsParameter(); - outputProps.setFileName(fileName); + outputProps.setFileName(configFile); //original eIDAS SAML-engine use this identifier outputProps.setName("fileConfiguration"); @@ -241,6 +245,8 @@ public class MOAeIDASSAMLEngineConfigurationImpl extends configFile, AuthConfigurationProviderFactory.getInstance().getRootConfigFileDir()); + Logger.debug("Load eIDAS configuration from file:" + absoluteConfigFile); + File file = new File(new URL(absoluteConfigFile).toURI()); is = new FileInputStream(file); props.loadFromXML(is); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLInstanceConfigurationImpl.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLInstanceConfigurationImpl.java index dccd39905..384d6be0b 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLInstanceConfigurationImpl.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLInstanceConfigurationImpl.java @@ -22,9 +22,22 @@ */ package at.gv.egovernment.moa.id.auth.modules.eidas.config; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; import java.util.List; +import java.util.Map.Entry; +import java.util.Properties; +import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.FileUtils; import eu.eidas.samlengineconfig.ConfigurationParameter; import eu.eidas.samlengineconfig.InstanceConfiguration; import eu.eidas.samlengineconfig.StringParameter; @@ -56,5 +69,49 @@ public class MOAeIDASSAMLInstanceConfigurationImpl extends addParameter(param); } + + public void addParameter(Properties parameters) { + Iterator<Entry<Object, Object>> paramInterator = parameters.entrySet().iterator(); + while (paramInterator.hasNext()) { + Entry<Object, Object> next = paramInterator.next(); + + StringParameter param = new StringParameter(); + String keyName = (String) next.getKey(); + param.setName(keyName); + + //make path to binary files absolute + if (Arrays.asList(MOAeIDASSAMLEngineConfigurationImpl.BINARY_PARAMETERS).contains(keyName)) + try { + String absoluteConfigFile = FileUtils.makeAbsoluteURL( + (String)next.getValue(), + AuthConfigurationProviderFactory.getInstance().getRootConfigFileDir()); + + URI uri = new URL(absoluteConfigFile).toURI(); + + File file = new File(uri); + if (file.exists()) + param.setValue(file.getCanonicalPath()); + + else { + Logger.error("eIDAS-configuration fileparameter with key:" + param.getName() + " and path:" + uri.toString() + " NOT exist!"); + param.setValue(null); + + } + + + } catch (ConfigurationException | URISyntaxException | IOException e) { + //TODO: make final!!!! + e.printStackTrace(); + param.setValue(next.getValue()); + + } + else + param.setValue(next.getValue()); + + addParameter(param); + + } + + } } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java index 1ba344fd1..9ad5f0db3 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java @@ -1,18 +1,95 @@ package at.gv.egovernment.moa.id.auth.modules.eidas.config; +import java.security.cert.X509Certificate; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; + +import com.google.common.collect.ImmutableMap; +import com.sun.istack.Nullable; + import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.logging.Logger; -import eu.eidas.auth.engine.core.impl.EncryptionSW; +import eu.eidas.auth.commons.EidasErrorKey; +import eu.eidas.auth.commons.io.ReloadableProperties; +import eu.eidas.auth.engine.configuration.SamlEngineConfigurationException; +import eu.eidas.auth.engine.configuration.dom.EncryptionKey; +import eu.eidas.auth.engine.core.impl.CertificateValidator; +import eu.eidas.auth.engine.core.impl.KeyStoreSamlEngineEncryption; +import eu.eidas.auth.engine.xml.opensaml.CertificateUtil; +import eu.eidas.engine.exceptions.EIDASSAMLEngineException; /** * This encryption module asks the moa configuration on whether to encrypt the response or not. In doubt, encryption is enforced. */ -public class ModifiedEncryptionSW extends EncryptionSW { +public class ModifiedEncryptionSW extends KeyStoreSamlEngineEncryption { + + private final ImmutableMap<String, String> properties; + + private final ReloadableProperties encryptionActivationProperties; + + private static ReloadableProperties initActivationConf(Map<String, String> properties) { + String activationConfigurationFile = EncryptionKey.ENCRYPTION_ACTIVATION.getAsString(properties); + Logger.debug("File containing encryption configuration: \"" + activationConfigurationFile + "\""); + return new ReloadableProperties(activationConfigurationFile); + } + + /** + * @param properties + * @throws SamlEngineConfigurationException + */ + public ModifiedEncryptionSW(Map<String, String> properties) throws SamlEngineConfigurationException { + super(properties); + this.properties = ImmutableMap.copyOf(properties); + encryptionActivationProperties = initActivationConf(properties); + } + + /* (non-Javadoc) + * @see eu.eidas.auth.engine.core.ProtocolEncrypterI#getEncryptionCertificate(java.lang.String) + */ + @Override + @Nullable + public X509Certificate getEncryptionCertificate(@Nullable String destinationCountryCode) + throws EIDASSAMLEngineException { + if (isEncryptionEnabled(destinationCountryCode)) { + String issuerKey = new StringBuilder(EncryptionKey.RESPONSE_TO_POINT_ISSUER_PREFIX.getKey()).append( + destinationCountryCode).toString(); + String serialNumberKey = + new StringBuilder(EncryptionKey.RESPONSE_TO_POINT_SERIAL_NUMBER_PREFIX.getKey()).append( + destinationCountryCode).toString(); + String serialNumber = properties.get(serialNumberKey); + String responseToPointIssuer = properties.get(issuerKey); + if (StringUtils.isNotBlank(responseToPointIssuer)) { + for (final X509Certificate certificate : getEncryptionCertificates()) { + if (CertificateUtil.matchesCertificate(serialNumber, responseToPointIssuer, certificate)) { + + if (isDisallowedSelfSignedCertificate()) { + CertificateValidator.checkCertificateIssuer(certificate); + } + if (isCheckedValidityPeriod()) { + CertificateValidator.checkCertificateValidityPeriod(certificate); + } + + return certificate; + } + } + throw new EIDASSAMLEngineException(EidasErrorKey.SAML_ENGINE_INVALID_CERTIFICATE.errorCode(), + EidasErrorKey.SAML_ENGINE_INVALID_CERTIFICATE.errorMessage()); + } else { + Logger.error("Encryption of SAML Response NOT done, because no \"" + issuerKey + + "\" configured!"); + } + } + return null; + } + /* (non-Javadoc) + * @see eu.eidas.auth.engine.core.ProtocolEncrypterI#isEncryptionEnabled(java.lang.String) + */ @Override - public boolean isEncryptionEnable(String countryCode) { + public boolean isEncryptionEnabled(String countryCode) { // - encrypt if so configured try { AuthConfiguration moaconfig = AuthConfigurationProviderFactory.getInstance(); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java new file mode 100644 index 000000000..c24c5efca --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java @@ -0,0 +1,57 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.eidas.engine; + +import eu.eidas.auth.engine.core.eidas.EidasProtocolProcessor; +import eu.eidas.auth.engine.metadata.MetadataFetcherI; +import eu.eidas.auth.engine.metadata.MetadataSignerI; + +/** + * @author tlenz + * + */ +public class MOAEidasProtocolProcesser extends EidasProtocolProcessor { + + private static final String OWN_EIDAS_RESPONSE_VALIDATOR_SUITE_ID = "moaEidasResponseValidatorSuiteId"; + + private final MetadataFetcherI metadataFetcher; + private final MetadataSignerI metadataSigner; + + /** + * @param metadataFetcher + * @param metadataSigner + */ + public MOAEidasProtocolProcesser(MetadataFetcherI metadataFetcher, MetadataSignerI metadataSigner) { + super(metadataFetcher, metadataSigner); + + this.metadataFetcher = metadataFetcher; + this.metadataSigner = metadataSigner; + + } + + @Override + public String getResponseValidatorId() { + return OWN_EIDAS_RESPONSE_VALIDATOR_SUITE_ID; + } + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java index 80a2734f2..7fb0dbb5f 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java @@ -18,58 +18,80 @@ import org.opensaml.saml2.metadata.EntitiesDescriptor; import org.opensaml.saml2.metadata.EntityDescriptor; import org.opensaml.saml2.metadata.RoleDescriptor; import org.opensaml.saml2.metadata.provider.ChainingMetadataProvider; -import org.opensaml.saml2.metadata.provider.FilterException; import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider; import org.opensaml.saml2.metadata.provider.MetadataFilter; import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.saml2.metadata.provider.MetadataProviderException; import org.opensaml.saml2.metadata.provider.ObservableMetadataProvider; import org.opensaml.xml.XMLObject; +import org.springframework.stereotype.Service; +import at.gv.egovernment.moa.id.auth.IDestroyableObject; +import at.gv.egovernment.moa.id.auth.IGarbageCollectorProcessing; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.ex.MOAHttpProtocolSocketFactoryException; import at.gv.egovernment.moa.id.commons.utils.MOAHttpProtocolSocketFactory; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; -import at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing; -import at.gv.egovernment.moa.id.config.auth.MOAGarbageCollector; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SchemaValidationException; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SignatureValidationException; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.MOASPMetadataSignatureFilter; import at.gv.egovernment.moa.id.saml2.MetadataFilterChain; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; -import eu.eidas.auth.engine.AbstractSAMLEngine; +import eu.eidas.auth.engine.AbstractProtocolEngine; -public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvider, IGarbageCollectorProcessing { +@Service("eIDASMetadataProvider") +public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvider, + IGarbageCollectorProcessing, IDestroyableObject { - private static MOAeIDASChainingMetadataProvider instance = null; +// private static MOAeIDASChainingMetadataProvider instance = null; private static Object mutex = new Object(); private MetadataProvider internalProvider; private Map<String, Date> lastAccess = null; - public static MOAeIDASChainingMetadataProvider getInstance() { - if (instance == null) { - synchronized (mutex) { - if (instance == null) { - instance = new MOAeIDASChainingMetadataProvider(); - MOAGarbageCollector.addModulForGarbageCollection(instance); - } - } - } - return instance; - } +// public static MOAeIDASChainingMetadataProvider getInstance() { +// if (instance == null) { +// synchronized (mutex) { +// if (instance == null) { +// instance = new MOAeIDASChainingMetadataProvider(); +// MOAGarbageCollector.addModulForGarbageCollection(instance); +// } +// } +// } +// return instance; +// } - private MOAeIDASChainingMetadataProvider() { + public MOAeIDASChainingMetadataProvider() { internalProvider = new ChainingMetadataProvider(); lastAccess = new HashMap<String, Date>(); } /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.auth.IDestroyableObject#fullyDestroy() + */ + @Override + public void fullyDestroy() { + Map<String, HTTPMetadataProvider> loadedproviders = getAllActuallyLoadedProviders(); + if (loadedproviders != null) { + for (Entry<String, HTTPMetadataProvider> el : loadedproviders.entrySet()) { + try { + el.getValue().destroy(); + Logger.debug("Destroy eIDAS Matadataprovider: " + el.getKey() + " finished"); + + } catch (Exception e) { + Logger.warn("Destroy eIDAS Matadataprovider: " + el.getKey() + " FAILED"); + + } + } + } + } + + /* (non-Javadoc) * @see at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing#runGarbageCollector() */ @Override @@ -128,9 +150,11 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi List<String> nonValidMetadataProvider = new ArrayList<String>(); for (HTTPMetadataProvider provider : loadedproviders.values()) { try { - provider.getMetadataFilter().doFilter(provider.getMetadata()); + provider.refresh(); + + //provider.getMetadataFilter().doFilter(provider.getMetadata()); - } catch (FilterException | MetadataProviderException e) { + } catch (MetadataProviderException e) { Logger.info("eIDAS MetadataProvider: " + provider.getMetadataURI() + " is not valid any more. Reason:" + e.getMessage()); if (Logger.isDebugEnabled()) @@ -196,10 +220,10 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi } } - timer = new Timer(); + timer = new Timer(true); httpProvider = new HTTPMetadataProvider(timer, httpClient, metadataURL); - httpProvider.setParserPool(AbstractSAMLEngine.getNewBasicSecuredParserPool()); + httpProvider.setParserPool(AbstractProtocolEngine.getSecuredParserPool()); httpProvider.setRequireValidMetadata(true); httpProvider.setMinRefreshDelay(1000*60*15); //15 minutes httpProvider.setMaxRefreshDelay(1000*60*60*24); //24 hours @@ -405,5 +429,4 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi if (observer != null) observer.onEvent(this); } - } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataProviderDecorator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataProviderDecorator.java index 7537c4d84..c5e56502b 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataProviderDecorator.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataProviderDecorator.java @@ -31,15 +31,17 @@ import org.opensaml.saml2.metadata.SPSSODescriptor; import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.saml2.metadata.provider.MetadataProviderException; -import eu.eidas.auth.engine.EIDASSAMLEngine; -import eu.eidas.auth.engine.metadata.MetadataProcessorI; +import eu.eidas.auth.engine.ProtocolEngineI; +import eu.eidas.auth.engine.metadata.MetadataFetcherI; +import eu.eidas.auth.engine.metadata.MetadataSignerI; +import eu.eidas.engine.exceptions.EIDASSAMLEngineException; import eu.eidas.engine.exceptions.SAMLEngineException; /** * @author tlenz * */ -public class MOAeIDASMetadataProviderDecorator implements MetadataProcessorI { +public class MOAeIDASMetadataProviderDecorator implements MetadataFetcherI { private MetadataProvider metadataprovider = null; @@ -51,10 +53,31 @@ public class MOAeIDASMetadataProviderDecorator implements MetadataProcessorI { } + /* (non-Javadoc) - * @see eu.eidas.auth.engine.metadata.MetadataProcessorI#getEntityDescriptor(java.lang.String) + * @see eu.eidas.auth.engine.metadata.MetadataFetcherI#getEntityDescriptor(java.lang.String, eu.eidas.auth.engine.metadata.MetadataSignerI) */ @Override + public EntityDescriptor getEntityDescriptor(String url, MetadataSignerI paramMetadataSignerI) + throws EIDASSAMLEngineException { + try { + /*TODO: maybe implement metadata signature validation on every request, + * but it is not needed in case of cached metadata provider, + * because signature must be only validated in case of cache reload operation + */ + return this.metadataprovider.getEntityDescriptor(url); + + } catch (MetadataProviderException e) { + throw new EIDASSAMLEngineException("eIDAS Metadata processing FAILED.", e); + + } + } + + + /* (non-Javadoc) + * @see eu.eidas.auth.engine.metadata.MetadataProcessorI#getEntityDescriptor(java.lang.String) + */ + @Deprecated public EntityDescriptor getEntityDescriptor(String url) throws SAMLEngineException { try { @@ -69,7 +92,7 @@ public class MOAeIDASMetadataProviderDecorator implements MetadataProcessorI { /* (non-Javadoc) * @see eu.eidas.auth.engine.metadata.MetadataProcessorI#getSPSSODescriptor(java.lang.String) */ - @Override + @Deprecated public SPSSODescriptor getSPSSODescriptor(String url) throws SAMLEngineException { return getFirstRoleDescriptor(getEntityDescriptor(url), SPSSODescriptor.class); @@ -79,7 +102,7 @@ public class MOAeIDASMetadataProviderDecorator implements MetadataProcessorI { /* (non-Javadoc) * @see eu.eidas.auth.engine.metadata.MetadataProcessorI#getIDPSSODescriptor(java.lang.String) */ - @Override + @Deprecated public IDPSSODescriptor getIDPSSODescriptor(String url) throws SAMLEngineException { return getFirstRoleDescriptor(getEntityDescriptor(url), IDPSSODescriptor.class); @@ -89,8 +112,8 @@ public class MOAeIDASMetadataProviderDecorator implements MetadataProcessorI { /* (non-Javadoc) * @see eu.eidas.auth.engine.metadata.MetadataProcessorI#checkValidMetadataSignature(java.lang.String, eu.eidas.auth.engine.EIDASSAMLEngine) */ - @Override - public void checkValidMetadataSignature(String url, EIDASSAMLEngine engine) + @Deprecated + public void checkValidMetadataSignature(String url, ProtocolEngineI engine) throws SAMLEngineException { //Do nothing, because metadata signature is already validated during //metadata provider initialization @@ -102,7 +125,7 @@ public class MOAeIDASMetadataProviderDecorator implements MetadataProcessorI { /* (non-Javadoc) * @see eu.eidas.auth.engine.metadata.MetadataProcessorI#checkValidMetadataSignature(java.lang.String, java.security.KeyStore) */ - @Override + @Deprecated public void checkValidMetadataSignature(String url, KeyStore trustStore) throws SAMLEngineException { //Do nothing, because metadata signature is already validated during @@ -110,6 +133,7 @@ public class MOAeIDASMetadataProviderDecorator implements MetadataProcessorI { } + @Deprecated protected <T extends RoleDescriptor> T getFirstRoleDescriptor(EntityDescriptor entityDescriptor, final Class<T> clazz){ for(RoleDescriptor rd:entityDescriptor.getRoleDescriptors()){ if(clazz.isInstance(rd)){ @@ -119,4 +143,6 @@ public class MOAeIDASMetadataProviderDecorator implements MetadataProcessorI { return null; } + + } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/validation/MoaEidasConditionsValidator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/validation/MoaEidasConditionsValidator.java new file mode 100644 index 000000000..d9453322f --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/validation/MoaEidasConditionsValidator.java @@ -0,0 +1,83 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.eidas.engine.validation; + +import org.joda.time.DateTime; +import org.opensaml.saml2.core.Conditions; +import org.opensaml.saml2.core.validator.ConditionsSpecValidator; +import org.opensaml.xml.validation.ValidationException; + +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + * MOA-ID specific eIDAS Response Condition validator + * + * This validator allows time jitter in 'notBefore' validation + * + */ + +public class MoaEidasConditionsValidator extends ConditionsSpecValidator { + + + + @Override + public void validate(Conditions conditions) throws ValidationException { + Logger.debug("conditions.getNotBefore() "+ conditions.getNotBefore()); + Logger.debug("conditions.getNotOnOrAfter() "+ conditions.getNotOnOrAfter()); + Logger.debug("dateTime.now() "+ DateTime.now()); + + super.validate(conditions); + + if (conditions.getNotBefore() == null) { + + throw new ValidationException("NotBefore is required."); + } + + if (conditions.getNotBefore().minusMillis(Constants.CONFIG_PROPS_SKEWTIME).isAfterNow()) { + throw new ValidationException("Current time is before NotBefore condition"); + } + + if (conditions.getNotOnOrAfter() == null) { + + throw new ValidationException("NotOnOrAfter is required."); + } + if (conditions.getNotOnOrAfter().isBeforeNow()) { + + throw new ValidationException("Current time is after NotOnOrAfter condition"); + } + + if (conditions.getAudienceRestrictions() == null || conditions.getAudienceRestrictions().isEmpty()) { + + throw new ValidationException("AudienceRestriction is required."); + } + + if (conditions.getOneTimeUse() == null) { + + throw new ValidationException("OneTimeUse is required."); + } + + } +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAuthnRequestProcessingException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASAuthnRequestProcessingException.java index c96af37ef..d51629d9e 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAuthnRequestProcessingException.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASAuthnRequestProcessingException.java @@ -30,7 +30,7 @@ import at.gv.egovernment.moa.util.MiscUtil; * @author tlenz * */ -public class eIDASAuthnRequestProcessingException extends eIDASException { +public class EIDASAuthnRequestProcessingException extends EIDASException { private String subStatusCode = null; @@ -43,20 +43,20 @@ public class eIDASAuthnRequestProcessingException extends eIDASException { * @param messageId * @param parameters */ - public eIDASAuthnRequestProcessingException(String messageId, Object[] parameters) { + public EIDASAuthnRequestProcessingException(String messageId, Object[] parameters) { super(messageId, parameters); } - public eIDASAuthnRequestProcessingException(String subStatusCode, String messageId, Object[] parameters) { + public EIDASAuthnRequestProcessingException(String subStatusCode, String messageId, Object[] parameters) { super(messageId, parameters); this.subStatusCode = subStatusCode; } - public eIDASAuthnRequestProcessingException(String messageId, Object[] parameters, Throwable e) { + public EIDASAuthnRequestProcessingException(String messageId, Object[] parameters, Throwable e) { super(messageId, parameters, e ); } - public eIDASAuthnRequestProcessingException(String subStatusCode, String messageId, Object[] parameters, Throwable e) { + public EIDASAuthnRequestProcessingException(String subStatusCode, String messageId, Object[] parameters, Throwable e) { super(messageId, parameters, e ); this.subStatusCode = subStatusCode; } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAuthnRequestValidationException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASAuthnRequestValidationException.java index 2a15ee18a..a6da769b7 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAuthnRequestValidationException.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASAuthnRequestValidationException.java @@ -28,7 +28,7 @@ import org.opensaml.saml2.core.StatusCode; * @author tlenz * */ -public class eIDASAuthnRequestValidationException extends eIDASException { +public class EIDASAuthnRequestValidationException extends EIDASException { /** * @@ -39,7 +39,7 @@ public class eIDASAuthnRequestValidationException extends eIDASException { * @param messageId * @param parameters */ - public eIDASAuthnRequestValidationException(String messageId, Object[] parameters) { + public EIDASAuthnRequestValidationException(String messageId, Object[] parameters) { super(messageId, parameters); } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineException.java index 234c4e038..8bf7f7452 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineException.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineException.java @@ -28,7 +28,7 @@ import org.opensaml.saml2.core.StatusCode; * @author tlenz * */ -public class EIDASEngineException extends eIDASException { +public class EIDASEngineException extends EIDASException { /** * @param objects diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASException.java index f42004abc..e3d6c5a2e 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASException.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASException.java @@ -28,7 +28,7 @@ import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; * @author tlenz * */ -public abstract class eIDASException extends MOAIDException { +public abstract class EIDASException extends MOAIDException { /** * @@ -44,7 +44,7 @@ public abstract class eIDASException extends MOAIDException { * @param messageId * @param parameters */ - public eIDASException(String messageId, Object[] parameters) { + public EIDASException(String messageId, Object[] parameters) { super(messageId, parameters); } @@ -52,7 +52,7 @@ public abstract class eIDASException extends MOAIDException { * @param messageId * @param parameters */ - public eIDASException(String messageId, Object[] parameters, Throwable e) { + public EIDASException(String messageId, Object[] parameters, Throwable e) { super(messageId, parameters, e); } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASResponseBuildException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASResponseBuildException.java index 0ffcf11ef..5e6b87b39 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASResponseBuildException.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASResponseBuildException.java @@ -28,7 +28,7 @@ import org.opensaml.saml2.core.StatusCode; * @author tlenz * */ -public class eIDASResponseBuildException extends eIDASException { +public class EIDASResponseBuildException extends EIDASException { /** * @@ -39,11 +39,11 @@ public class eIDASResponseBuildException extends eIDASException { * @param messageId * @param parameters */ - public eIDASResponseBuildException(String messageId, Object[] parameters) { + public EIDASResponseBuildException(String messageId, Object[] parameters) { super(messageId, parameters); } - public eIDASResponseBuildException(String messageId, Object[] parameters, Throwable e) { + public EIDASResponseBuildException(String messageId, Object[] parameters, Throwable e) { super(messageId, parameters, e); } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASResponseNotSuccessException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASResponseNotSuccessException.java index d10ca1c88..460561eb3 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASResponseNotSuccessException.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASResponseNotSuccessException.java @@ -28,14 +28,14 @@ import org.opensaml.saml2.core.StatusCode; * @author tlenz * */ -public class eIDASResponseNotSuccessException extends eIDASException { +public class EIDASResponseNotSuccessException extends EIDASException { /** * */ private static final long serialVersionUID = 6145402939313568907L; - public eIDASResponseNotSuccessException(String messageId, Object[] parameters) { + public EIDASResponseNotSuccessException(String messageId, Object[] parameters) { super(messageId, parameters); } @@ -44,7 +44,7 @@ public class eIDASResponseNotSuccessException extends eIDASException { * @param parameters * @param e */ - public eIDASResponseNotSuccessException(String messageId, Object[] parameters, Throwable e) { + public EIDASResponseNotSuccessException(String messageId, Object[] parameters, Throwable e) { super(messageId, parameters, e); } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAttributeException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAttributeException.java index b25895eca..17f0a9b72 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAttributeException.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAttributeException.java @@ -28,7 +28,7 @@ import org.opensaml.saml2.core.StatusCode; * @author tlenz * */ -public class eIDASAttributeException extends eIDASException { +public class eIDASAttributeException extends EIDASException { private static final long serialVersionUID = 1L; diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CreateIdentityLinkTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CreateIdentityLinkTask.java index 5d7430dd7..6be64ba72 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CreateIdentityLinkTask.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CreateIdentityLinkTask.java @@ -28,6 +28,7 @@ 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; @@ -39,6 +40,7 @@ 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.exceptions.MOAIDException; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; @@ -47,7 +49,7 @@ 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.IPersonalAttributeList; +import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; /** * @author tlenz @@ -67,9 +69,9 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask { defaultTaskInitialization(request, executionContext); //get eIDAS attributes from MOA-Session - IPersonalAttributeList eIDASAttributes = moasession.getGenericDataFromSession( + ImmutableAttributeMap eIDASAttributes = moasession.getGenericDataFromSession( AuthenticationSessionStorageConstants.eIDAS_ATTRIBUTELIST, - IPersonalAttributeList.class); + ImmutableAttributeMap.class); IdentityLink identityLink = null; @@ -86,35 +88,51 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask { // replace data Element idlassertion = identityLink.getSamlAssertion(); - - // - set bpk/wpbk; + + // - set fake baseID; Node prIdentification = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH); - if(!eIDASAttributes.containsKey(Constants.eIDAS_ATTR_PERSONALIDENTIFIER)) - throw new eIDASAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); - String eIdentifier = eIDASAttributes.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER).getValue().get(0); - prIdentification.getFirstChild().setNodeValue(eIdentifier); + + + 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); - if(!eIDASAttributes.containsKey(Constants.eIDAS_ATTR_CURRENTFAMILYNAME)) + 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); - String familyName = eIDASAttributes.get(Constants.eIDAS_ATTR_CURRENTFAMILYNAME).getValue().get(0); - prFamilyName.getFirstChild().setNodeValue(familyName); + prFamilyName.getFirstChild().setNodeValue((String) familyName); // - set first name Node prGivenName = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_GIVEN_NAME_XPATH); - if(!eIDASAttributes.containsKey(Constants.eIDAS_ATTR_CURRENTGIVENNAME)) + Object givenName = eIDASAttributes.getFirstValue( + SAMLEngineUtils.getMapOfAllAvailableAttributes().get( + Constants.eIDAS_ATTR_CURRENTGIVENNAME)); + if (givenName == null || !(givenName instanceof String)) throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTGIVENNAME); - String givenName = eIDASAttributes.get(Constants.eIDAS_ATTR_CURRENTGIVENNAME).getValue().get(0); - prGivenName.getFirstChild().setNodeValue(givenName); + prGivenName.getFirstChild().setNodeValue((String) givenName); // - set date of birth - Node prDateOfBirth = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_DATE_OF_BIRTH_XPATH); - if(!eIDASAttributes.containsKey(Constants.eIDAS_ATTR_DATEOFBIRTH)) + 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 dateOfBirth = eIDASAttributes.get(Constants.eIDAS_ATTR_DATEOFBIRTH).getValue().get(0); - dateOfBirth = new SimpleDateFormat("yyyy-MM-dd").format(new SimpleDateFormat("yyyyMMdd").parse(dateOfBirth)); - prDateOfBirth.getFirstChild().setNodeValue(dateOfBirth); + + String formatedDateOfBirth = new SimpleDateFormat("yyyy-MM-dd").format(((DateTime)dateOfBirth).toDate()); + prDateOfBirth.getFirstChild().setNodeValue(formatedDateOfBirth); identityLink = new IdentityLinkAssertionParser(idlassertion).parseIdentityLink(); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java index 84b0078b3..3522a16fd 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java @@ -23,7 +23,9 @@ package at.gv.egovernment.moa.id.auth.modules.eidas.tasks; import java.io.StringWriter; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -33,6 +35,11 @@ import org.apache.commons.lang3.StringUtils; 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 com.google.common.net.MediaType; @@ -43,6 +50,7 @@ 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.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.utils.SAMLEngineUtils; import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; @@ -52,15 +60,17 @@ 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.logging.Logger; -import eu.eidas.auth.commons.EIDASAuthnRequest; -import eu.eidas.auth.commons.EIDASUtil; -import eu.eidas.auth.commons.EidasLoaCompareType; -import eu.eidas.auth.commons.EidasLoaLevels; -import eu.eidas.auth.commons.IPersonalAttributeList; -import eu.eidas.auth.commons.PersonalAttribute; -import eu.eidas.auth.commons.PersonalAttributeList; -import eu.eidas.auth.engine.EIDASSAMLEngine; -import eu.eidas.auth.engine.core.eidas.SPType; +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.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; +import eu.eidas.auth.engine.ProtocolEngineI; import eu.eidas.engine.exceptions.EIDASSAMLEngineException; /** @@ -70,6 +80,8 @@ import eu.eidas.engine.exceptions.EIDASSAMLEngineException; @Component("GenerateAuthnRequestTask") public class GenerateAuthnRequestTask extends AbstractAuthServletTask { + @Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider; + /* (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) */ @@ -82,23 +94,61 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { //get service-provider configuration IOAAuthParameters oaConfig = pendingReq.getOnlineApplicationConfiguration(); - // get target country + // 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().getCPEPS(citizenCountryCode); if(null == cpeps) { Logger.error("PEPS unknown for country", new Object[] {citizenCountryCode}); throw new AuthenticationException("eIDAS.04", new Object[] {citizenCountryCode}); } Logger.debug("Found eIDaS Node/C-PEPS configuration for citizen of country: " + citizenCountryCode); - String destination = cpeps.getPepsURL().toString().split(";")[1].trim(); // FIXME convenience for metadata url and assertion destination + + + // select SingleSignOnService Endpoint from eIDAS-node metadata + String destination = null; String metadataUrl = cpeps.getPepsURL().toString().split(";")[0].trim(); + try { + EntityDescriptor eIDASNodeMetadata = eIDASMetadataProvider.getEntityDescriptor(metadataUrl); + if (eIDASNodeMetadata != null) { + SingleSignOnService ssoDescr = selectSingleSignOnServiceFromMetadata(eIDASNodeMetadata); + if (ssoDescr != null) { + destination = ssoDescr.getLocation(); + Logger.debug("Use destination URL:" + destination + " from eIDAS metadata:" + metadataUrl); + + } else + Logger.warn("eIDAS metadata for node:" + metadataUrl + " has no IDPSSODescriptor or no SingleSignOnService information."); + + } else + Logger.warn("No eIDAS metadata for node:" + metadataUrl + " "); + + } catch (MetadataProviderException e) { + Logger.warn("Load eIDAS metadata from node:" + metadataUrl + " FAILED with an error.", e); + + } + // load SingleSignOnService Endpoint from configuration, if Metadata contains no information + // FIXME convenience function for not standard conform metadata + if (MiscUtil.isEmpty(destination)) { + String[] splitString = cpeps.getPepsURL().toString().split(";"); + if (splitString.length > 1) + destination = cpeps.getPepsURL().toString().split(";")[1].trim(); + + if (MiscUtil.isNotEmpty(destination)) + Logger.debug("Use eIDAS node destination URL:" + destination + " from configuration"); + + else { + Logger.error("No eIDAS-node destination URL FOUND. Request eIDAS node not possible."); + throw new MOAIDException("eIDAS.02", new Object[]{"No eIDAS-node Destination-URL FOUND"}); + + } + + } //TODO: switch to entityID revisionsLogger.logEvent(oaConfig, pendingReq, @@ -109,50 +159,71 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { Collection<StorkAttribute> attributesFromConfig = oaConfig.getRequestedSTORKAttributes(); // - prepare attribute list - IPersonalAttributeList pAttList = new PersonalAttributeList(); - + ProtocolEngineI engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); + // - fill container - for (StorkAttribute current : attributesFromConfig) { - PersonalAttribute newAttribute = new PersonalAttribute(); - newAttribute.setName(current.getName()); - - boolean globallyMandatory = false; - for (StorkAttribute currentGlobalAttribute : authConfig.getStorkConfig().getStorkAttributes()) - if (current.getName().equals(currentGlobalAttribute.getName())) { - globallyMandatory = BooleanUtils.isTrue(currentGlobalAttribute.getMandatory()); - break; - } - - newAttribute.setIsRequired(current.getMandatory() || globallyMandatory); - pAttList.add(newAttribute); + List<AttributeDefinition<?>> reqAttrList = new ArrayList<AttributeDefinition<?>>(); + 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()); + + } } - - EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); - - //build eIDAS AuthnRequest - EIDASAuthnRequest authnRequest = new EIDASAuthnRequest(); - authnRequest.setProviderName(pendingReq.getAuthURL()); - authnRequest.setPersonalAttributeList(pAttList); - authnRequest.setIssuer(pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_METADATA); + //build requested attribute set + ImmutableAttributeMap reqAttrMap = new ImmutableAttributeMap.Builder().putAll(reqAttrList).build(); + + //build eIDAS AuthnRequest + EidasAuthenticationRequest.Builder authnRequestBuilder = new EidasAuthenticationRequest.Builder(); + + authnRequestBuilder.id(eu.eidas.auth.engine.xml.opensaml.SAMLEngineUtils.generateNCName()); + authnRequestBuilder.providerName(pendingReq.getAuthURL()); + String issur = pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_METADATA; + authnRequestBuilder.issuer(issur); + authnRequestBuilder.destination(destination); + + authnRequestBuilder.nameIdFormat(Constants.eIDAS_REQ_NAMEID_FORMAT); - authnRequest.setDestination(destination); - authnRequest.setEidasNameidFormat(EIDASAuthnRequest.NAMEID_FORMAT_UNSPECIFIED); - authnRequest.setEidasLoA(EidasLoaLevels.LOW.stringValue()); - authnRequest.setEidasLoACompareType(EidasLoaCompareType.MINIMUM.stringValue()); + //set minimum required eIDAS LoA from OA config + authnRequestBuilder.levelOfAssurance(LevelOfAssurance.fromString(oaConfig.getQaaLevel())); + authnRequestBuilder.levelOfAssuranceComparison(LevelOfAssuranceComparison.MINIMUM); //set correct SPType for this online application if (oaConfig.getBusinessService()) - authnRequest.setSPType("private"); + authnRequestBuilder.spType(SpType.PRIVATE); else - authnRequest.setSPType(SPType.DEFAULT_VALUE); - - engine.initRequestedAttributes(pAttList); - authnRequest = engine.generateEIDASAuthnRequest(authnRequest); + authnRequestBuilder.spType(SpType.PUBLIC); + + + //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); + + + IRequestMessage authnRequest = engine.generateRequestMessage(authnRequestBuilder.build(), issur); //encode AuthnRequest - byte[] token = authnRequest.getTokenSaml(); - String SAMLRequest = EIDASUtil.encodeSAMLToken(token); + byte[] token = authnRequest.getMessageBytes(); + String SAMLRequest = EidasStringUtil.encodeToBase64(token); //send @@ -187,7 +258,7 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { revisionsLogger.logEvent(oaConfig, pendingReq, MOAIDEventConstants.AUTHPROCESS_PEPS_REQUESTED, - authnRequest.getSamlId()); + authnRequest.getRequest().getId()); } catch (Exception e) { Logger.error("Velocity general error: " + e.getMessage()); @@ -209,4 +280,28 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { } } + 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; + +// else if ( sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI) +// && endpoint == null ) +// endpoint = sss; + + } + + return endpoint; + } + } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java index fae06031a..7ba5aee1e 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java @@ -4,6 +4,7 @@ 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; @@ -11,9 +12,9 @@ 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.MOAPersonalAttributeList; +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; @@ -21,14 +22,17 @@ import at.gv.egovernment.moa.id.process.api.ExecutionContext; 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.EIDASAuthnResponse; -import eu.eidas.auth.commons.EIDASUtil; -import eu.eidas.auth.engine.EIDASSAMLEngine; +import eu.eidas.auth.commons.EidasStringUtil; +import eu.eidas.auth.commons.protocol.IAuthenticationResponse; +import eu.eidas.auth.commons.protocol.eidas.LevelOfAssurance; +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 { @@ -45,40 +49,59 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { defaultTaskInitialization(request, executionContext); //decode SAML response - byte[] decSamlToken = EIDASUtil.decodeSAMLToken(base64SamlToken); + byte[] decSamlToken = EidasStringUtil.decodeBytesFromBase64(base64SamlToken); //get eIDAS SAML-engine - EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); - + ProtocolEngineI engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); + //validate SAML token - EIDASAuthnResponse samlResp = engine.validateEIDASAuthnResponse(decSamlToken, - request.getRemoteHost(), Constants.CONFIG_PROPS_SKEWTIME); - - boolean encryptedResponse=engine.isEncryptedSamlResponse(decSamlToken); - if (encryptedResponse) { + IAuthenticationResponse samlResp = engine.unmarshallResponseAndValidate(decSamlToken, + request.getRemoteHost(), + Constants.CONFIG_PROPS_SKEWTIME, + 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.getMessage()); - throw new eIDASResponseNotSuccessException("eIDAS.11", new Object[]{samlResp.getMessage()}); + + " Subcode:" + samlResp.getSubStatusCode() + " Msg:" + samlResp.getStatusMessage()); + throw new EIDASResponseNotSuccessException("eIDAS.11", new Object[]{samlResp.getStatusMessage()}); + + } + + // ********************************************************** + // ******* MOA-ID specific response validation ********** + // ********************************************************** + + //validate received LoA against minimum required LoA + LevelOfAssurance reqLoA = LevelOfAssurance.fromString(pendingReq.getOnlineApplicationConfiguration().getQaaLevel()); + LevelOfAssurance respLoA = LevelOfAssurance.fromString(samlResp.getLevelOfAssurance()); + if (respLoA.numericValue() < reqLoA.numericValue()) { + Logger.error("eIDAS Response LevelOfAssurance is lower than the required! " + + "(Resp-LoA:" + respLoA.getValue() + " Req-LoA:" + reqLoA.getValue() + ")"); + throw new MOAIDException("eIDAS.14", new Object[]{respLoA.getValue()}); } + - //MOA-ID specific response validation - //TODO: implement MOA-ID specific response validation + // ********************************************************** + // ******* 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.getAssuranceLevel()); + + moasession.setQAALevel(samlResp.getLevelOfAssurance()); moasession.setGenericDataToSession( AuthenticationSessionStorageConstants.eIDAS_ATTRIBUTELIST, - new MOAPersonalAttributeList(samlResp.getPersonalAttributeList())); + samlResp.getAttributes()); moasession.setGenericDataToSession( AuthenticationSessionStorageConstants.eIDAS_RESPONSE, @@ -92,13 +115,16 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq, MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED, - samlResp.getSamlId()); + samlResp.getId()); + + } catch (MOAIDException e) { + throw new TaskExecutionException(pendingReq, "eIDAS Response processing FAILED.", e); }catch (EIDASSAMLEngineException e) { Logger.error("eIDAS AuthnRequest generation FAILED.", e); revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq, MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED_ERROR); - throw new TaskExecutionException(pendingReq, "eIDAS AuthnRequest generation FAILED.", + throw new TaskExecutionException(pendingReq, "eIDAS Response processing FAILED.", new EIDASEngineException("eIDAS.09", new Object[]{e.getMessage()}, e)); } catch (MOADatabaseException e) { diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAOrderedAttributeIterator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAOrderedAttributeIterator.java deleted file mode 100644 index 573163af0..000000000 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAOrderedAttributeIterator.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2014 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - */ -package at.gv.egovernment.moa.id.auth.modules.eidas.utils; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import at.gv.egovernment.moa.logging.Logger; - -import eu.eidas.auth.commons.PersonalAttribute; -import eu.eidas.auth.commons.PersonalAttributeList; - - -/** - * @author tlenz - * - */ -public class MOAOrderedAttributeIterator implements Iterator<PersonalAttribute> { - - private MOAPersonalAttributeList pal; - private Iterator<String> keyIterator; - - public MOAOrderedAttributeIterator(MOAPersonalAttributeList palArg) { - this.pal = palArg; - keyIterator = palArg.getInsertOrder().iterator(); - } - - @Override - public boolean hasNext() { - return keyIterator.hasNext(); - } - - @Override - public PersonalAttribute next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - return pal.get(keyIterator.next()); - } - - @Override - public void remove() { - Logger.error("Not implemented"); - } - -} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAPersonalAttributeList.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAPersonalAttributeList.java deleted file mode 100644 index 5cc100b70..000000000 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAPersonalAttributeList.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright 2014 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - */ -package at.gv.egovernment.moa.id.auth.modules.eidas.utils; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.commons.lang.StringUtils; - -import at.gv.egovernment.moa.logging.Logger; - -import eu.eidas.auth.commons.AttributeConstants; -import eu.eidas.auth.commons.AttributeUtil; -import eu.eidas.auth.commons.EIDASErrors; -import eu.eidas.auth.commons.EIDASParameters; -import eu.eidas.auth.commons.EIDASUtil; -import eu.eidas.auth.commons.EIDASValues; -import eu.eidas.auth.commons.IPersonalAttributeList; -import eu.eidas.auth.commons.PersonalAttribute; -import eu.eidas.auth.commons.exceptions.InternalErrorEIDASException; - -/** - * @author tlenz - * - */ -public final class MOAPersonalAttributeList extends - ConcurrentHashMap<String, PersonalAttribute> implements IPersonalAttributeList { - - /** - * - */ - private static final long serialVersionUID = -4488124133022713089L; - - public MOAPersonalAttributeList(IPersonalAttributeList eIDASAttributeList) { - super(); - Iterator<PersonalAttribute> element = eIDASAttributeList.iterator(); - while(element.hasNext()) - add(element.next()); - - } - - /** - * Hash with the latest fetched attribute name alias. - */ - private Map<String, Integer> latestAttrAlias = - new HashMap<String, Integer>(); - - /** - * Hash with mapping number of alias or the attribute name. - */ - private Map<String, Integer> attrAliasNumber = - new HashMap<String, Integer>(); - private List<String> insertOrder = new ArrayList<String>(); - - /** - * Obtain the insertOrder Collection - * - * @return defensive copy of the collection - */ - List<String> getInsertOrder() { - return Collections.unmodifiableList(this.insertOrder); - } - - /** - * Default constructor. - */ - public MOAPersonalAttributeList() { - super(); - - } - - /** - * Constructor with initial capacity for the PersonalAttributeList size. - * - * @param capacity The initial capacity for the PersonalAttributeList. - */ - public MOAPersonalAttributeList(final int capacity) { - super(capacity); - } - - /** - * {@inheritDoc} - */ - public Iterator<PersonalAttribute> iterator() { - return new MOAOrderedAttributeIterator(this); - } - - /** - * {@inheritDoc} - */ - public PersonalAttribute get(final Object key) { - String attrName = (String) key; - - if (this.latestAttrAlias == null) - this.latestAttrAlias = new HashMap<String, Integer>(); - - if (this.attrAliasNumber == null) - this.attrAliasNumber = new HashMap<String, Integer>(); - - if (this.latestAttrAlias.containsKey(key)) { - attrName = attrName + this.latestAttrAlias.get(key); - } else { - if (this.attrAliasNumber.containsKey(key)) { - this.latestAttrAlias.put(attrName, this.attrAliasNumber.get(key)); - } - } - return super.get(attrName); - } - - /** - * {@inheritDoc} - */ - public void add(final PersonalAttribute value) { - if (value != null) { - this.put(value.getName(), value); - } - } - - /** - * {@inheritDoc} - */ - public PersonalAttribute put(final String key, final PersonalAttribute val) { - if (StringUtils.isNotEmpty(key) && val != null) { - // Validate if attribute name already exists! - String attrAlias = key; - if (this.containsKey(attrAlias)) { - if (this.attrAliasNumber == null) - this.attrAliasNumber = new HashMap<String, Integer>(); - if (!val.isEmptyValue() && StringUtils.isNumeric(val.getValue().get(0))) { - final String attrValue = val.getValue().get(0); - attrAlias = key + attrValue; - this.attrAliasNumber.put(key, Integer.valueOf(attrValue)); - } else { - final PersonalAttribute attr = super.get(key); - if (!attr.isEmptyValue() - && StringUtils.isNumeric(attr.getValue().get(0))) { - attrAlias = key + attr.getValue().get(0); - super.put(key, (PersonalAttribute) attr); - this.attrAliasNumber.put(key, null); - } - } - } else { - if (insertOrder == null) - insertOrder = new ArrayList<String>(); - - insertOrder.add(key); - } - return super.put(attrAlias, val); - } else { - return null; - } - } - - @Override - public PersonalAttribute remove(Object key) { - insertOrder.remove(key); - return super.remove(key); - } - - /** - * {@inheritDoc} - */ - public void populate(final String attrList) { - final StringTokenizer strToken = - new StringTokenizer(attrList, EIDASValues.ATTRIBUTE_SEP.toString()); - - while (strToken.hasMoreTokens()) { - final PersonalAttribute persAttr = new PersonalAttribute(); - String[] tuples = - strToken.nextToken().split(EIDASValues.ATTRIBUTE_TUPLE_SEP.toString(), - AttributeConstants.NUMBER_TUPLES.intValue()); - - // Convert to the new format if needed! - tuples = convertFormat(tuples); - - if (AttributeUtil.hasValidTuples(tuples)) { - final int attrValueIndex = - AttributeConstants.ATTR_VALUE_INDEX.intValue(); - final String tmpAttrValue = - tuples[attrValueIndex].substring(1, - tuples[attrValueIndex].length() - 1); - final String[] vals = - tmpAttrValue.split(EIDASValues.ATTRIBUTE_VALUE_SEP.toString()); - - persAttr.setName(tuples[AttributeConstants.ATTR_NAME_INDEX.intValue()]); - persAttr.setIsRequired(Boolean - .valueOf(tuples[AttributeConstants.ATTR_TYPE_INDEX.intValue()])); - // check if it is a complex value - if (tuples[AttributeConstants.ATTR_NAME_INDEX.intValue()] - .equals(EIDASParameters.COMPLEX_ADDRESS_VALUE.toString())) { - persAttr.setComplexValue(createComplexValue(vals)); - } else { - persAttr.setValue(createValues(vals)); - } - - if (tuples.length == AttributeConstants.NUMBER_TUPLES.intValue()) { - persAttr.setStatus(tuples[AttributeConstants.ATTR_STATUS_INDEX - .intValue()]); - } - this.put(tuples[AttributeConstants.ATTR_NAME_INDEX.intValue()], - persAttr); - - } else { - Logger.info("BUSINESS EXCEPTION : Invalid personal attribute list tuples"); - } - - } - } - - /** - * Returns a copy of this <tt>IPersonalAttributeList</tt> instance. - * - * @return The copy of this IPersonalAttributeList. - */ - public Object clone() { - try { - MOAPersonalAttributeList theClone= (MOAPersonalAttributeList)super.clone(); - theClone.insertOrder=new ArrayList<String>(insertOrder); - return theClone; - - } catch (CloneNotSupportedException e) { - throw new InternalErrorEIDASException( - EIDASUtil.getConfig(EIDASErrors.INTERNAL_ERROR.errorCode()), - EIDASUtil.getConfig(EIDASErrors.INTERNAL_ERROR.errorMessage()), e); - } - } - - /** - * Creates a string in the following format. - * - * attrName:attrType:[attrValue1,attrValue2=attrComplexValue]:attrStatus; - * - * @return {@inheritDoc} - */ - @Override - public String toString() { - final StringBuilder strBuilder = new StringBuilder(); - final Iterator<String> iteratorInsertOrder = insertOrder.iterator(); - while (iteratorInsertOrder.hasNext()) { - String key = iteratorInsertOrder.next(); - final PersonalAttribute attr = get(key); - strBuilder.append(attr.toString()); - if (isNumberAlias(key)) { - strBuilder.append(get(key).toString()); - } - } - return strBuilder.toString(); - } - - /** - * Validates and creates the attribute's complex values. - * - * @param values The complex values. - * @return The {@link Map} with the complex values. - * @see Map - */ - private Map<String, String> createComplexValue(final String[] values) { - final Map<String, String> complexValue = new HashMap<String, String>(); - for (final String val : values) { - final String[] tVal = val.split("="); - if (StringUtils.isNotEmpty(val) && tVal.length == 2) { - complexValue.put(tVal[0], AttributeUtil.unescape(tVal[1])); - } - } - return complexValue; - } - - /** - * Validates and creates the attribute values. - * - * @param vals The attribute values. - * @return The {@link List} with the attribute values. - * @see List - */ - private List<String> createValues(final String[] vals) { - final List<String> values = new ArrayList<String>(); - for (final String val : vals) { - if (StringUtils.isNotEmpty(val)) { - values.add(AttributeUtil.unescape(val)); - } - } - return values; - } - - ////////////////// - /** - * Converts the attribute tuple (attrName:attrType...) to the new format. - * - * @param tuples The attribute tuples to convert. - * @return The attribute tuples in the new format. - */ - private String[] convertFormat(final String[] tuples) { - final String[] newFormatTuples = - new String[AttributeConstants.NUMBER_TUPLES.intValue()]; - if (tuples != null) { - System.arraycopy(tuples, 0, newFormatTuples, 0, tuples.length); - - for (int i = tuples.length; i < newFormatTuples.length; i++) { - if (i == AttributeConstants.ATTR_VALUE_INDEX.intValue()) { - newFormatTuples[i] = "[]"; - } else { - newFormatTuples[i] = ""; - } - } - } - return newFormatTuples; - } - - public boolean isNumberAlias(String key) { - return this.attrAliasNumber.containsKey(key); - } - - - -} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAProtocolEngineFactory.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAProtocolEngineFactory.java new file mode 100644 index 000000000..f29d2bb65 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAProtocolEngineFactory.java @@ -0,0 +1,99 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.eidas.utils; + +import at.gv.egovernment.moa.id.auth.modules.eidas.config.MOAIDCertificateManagerConfigurationImpl; +import at.gv.egovernment.moa.logging.Logger; +import eu.eidas.auth.engine.ProtocolEngineFactory; +import eu.eidas.auth.engine.configuration.SamlEngineConfigurationException; +import eu.eidas.auth.engine.configuration.dom.ProtocolEngineConfigurationFactory; +import eu.eidas.samlengineconfig.CertificateConfigurationManager; + +/** + * @author tlenz + * + */ +public class MOAProtocolEngineFactory extends ProtocolEngineFactory { + + /** + * Initialization-on-demand holder idiom. + * <p/> + * See item 71 of Effective Java 2nd Edition. + * <p/> + * See http://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom. + */ + private static final class LazyHolder { + + private static final MOAProtocolEngineFactory DEFAULT_SAML_ENGINE_FACTORY; + + private static final Exception INITIALIZATION_EXCEPTION; + + static { + Exception initializationException = null; + MOAProtocolEngineFactory defaultProtocolEngineFactory = null; + try { + //get eIDAS SAMLengine configuration from MOA-ID configuration + CertificateConfigurationManager configManager = new MOAIDCertificateManagerConfigurationImpl(); + + ProtocolEngineConfigurationFactory engineConfigurationFactory = new ProtocolEngineConfigurationFactory(configManager); + defaultProtocolEngineFactory = new MOAProtocolEngineFactory(engineConfigurationFactory); + + } catch (Exception ex) { + initializationException = ex; + Logger.error("Unable to instantiate default SAML engines: " + ex, ex); + + } + + DEFAULT_SAML_ENGINE_FACTORY = defaultProtocolEngineFactory; + INITIALIZATION_EXCEPTION = initializationException; + } + + static MOAProtocolEngineFactory getDefaultSamlEngineFactory() { + if (null == INITIALIZATION_EXCEPTION) { + return DEFAULT_SAML_ENGINE_FACTORY; + + } else { + throw new IllegalStateException(INITIALIZATION_EXCEPTION); + + } + } + } + + + public static MOAProtocolEngineFactory getInstance() { + return LazyHolder.getDefaultSamlEngineFactory(); + + } + + /** + * @param configurationFactory + * @throws SamlEngineConfigurationException + */ + private MOAProtocolEngineFactory(ProtocolEngineConfigurationFactory configurationFactory) + throws SamlEngineConfigurationException { + super(configurationFactory); + + } + + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java new file mode 100644 index 000000000..09c3dff38 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java @@ -0,0 +1,621 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.eidas.utils; + +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.DateTime; +import org.joda.time.DurationFieldType; +import org.opensaml.Configuration; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.common.Extensions; +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.core.AttributeValue; +import org.opensaml.saml2.metadata.AssertionConsumerService; +import org.opensaml.saml2.metadata.Company; +import org.opensaml.saml2.metadata.ContactPerson; +import org.opensaml.saml2.metadata.ContactPersonTypeEnumeration; +import org.opensaml.saml2.metadata.EmailAddress; +import org.opensaml.saml2.metadata.EncryptionMethod; +import org.opensaml.saml2.metadata.EntitiesDescriptor; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.GivenName; +import org.opensaml.saml2.metadata.IDPSSODescriptor; +import org.opensaml.saml2.metadata.KeyDescriptor; +import org.opensaml.saml2.metadata.LocalizedString; +import org.opensaml.saml2.metadata.NameIDFormat; +import org.opensaml.saml2.metadata.Organization; +import org.opensaml.saml2.metadata.OrganizationDisplayName; +import org.opensaml.saml2.metadata.OrganizationURL; +import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.saml2.metadata.SSODescriptor; +import org.opensaml.saml2.metadata.SingleSignOnService; +import org.opensaml.saml2.metadata.SurName; +import org.opensaml.saml2.metadata.TelephoneNumber; +import org.opensaml.samlext.saml2mdattr.EntityAttributes; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.XMLObjectBuilderFactory; +import org.opensaml.xml.schema.XSString; +import org.opensaml.xml.schema.impl.XSStringBuilder; +import org.opensaml.xml.security.SecurityException; +import org.opensaml.xml.security.credential.Credential; +import org.opensaml.xml.security.credential.UsageType; +import org.opensaml.xml.security.keyinfo.KeyInfoGenerator; +import org.opensaml.xml.security.x509.X509KeyInfoGeneratorFactory; +import org.opensaml.xml.signature.KeyInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.Ordering; + +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import eu.eidas.auth.commons.EIDASUtil; +import eu.eidas.auth.commons.EidasStringUtil; +import eu.eidas.auth.commons.attribute.AttributeDefinition; +import eu.eidas.auth.commons.protocol.impl.SamlNameIdFormat; +import eu.eidas.auth.commons.xml.opensaml.OpenSamlHelper; +import eu.eidas.auth.engine.ProtocolEngineI; +import eu.eidas.auth.engine.core.SAMLExtensionFormat; +import eu.eidas.auth.engine.core.eidas.DigestMethod; +import eu.eidas.auth.engine.core.eidas.EidasConstants; +import eu.eidas.auth.engine.core.eidas.SPType; +import eu.eidas.auth.engine.core.eidas.SigningMethod; +import eu.eidas.auth.engine.metadata.Contact; +import eu.eidas.auth.engine.metadata.EntityDescriptorContainer; +import eu.eidas.auth.engine.metadata.MetadataConfigParams; +import eu.eidas.auth.engine.metadata.MetadataGenerator; +import eu.eidas.auth.engine.metadata.MetadataSignerI; +import eu.eidas.auth.engine.xml.opensaml.BuilderFactoryUtil; +import eu.eidas.auth.engine.xml.opensaml.CertificateUtil; +import eu.eidas.encryption.exception.UnmarshallException; +import eu.eidas.engine.exceptions.EIDASSAMLEngineException; +import eu.eidas.engine.exceptions.SAMLEngineException; + +/** + * @author tlenz + * + */ +public class MOAeIDASMetadataGenerator extends MetadataGenerator { + private static final Logger LOGGER = LoggerFactory.getLogger(MetadataGenerator.class.getName()); + + MetadataConfigParams params; + + XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory(); + + SPSSODescriptor spSSODescriptor = null; + + IDPSSODescriptor idpSSODescriptor = null; + + private String ssoLocation; + + /** + * @return a String representation of the entityDescriptr built based on the attributes previously set + */ + public String generateMetadata() throws EIDASSAMLEngineException { + EntityDescriptor entityDescriptor; + try { + entityDescriptor = (EntityDescriptor) builderFactory.getBuilder(EntityDescriptor.DEFAULT_ELEMENT_NAME) + .buildObject(EntityDescriptor.DEFAULT_ELEMENT_NAME); + + entityDescriptor.setEntityID(params.getEntityID()); + entityDescriptor.setOrganization(buildOrganization()); + entityDescriptor.getContactPersons().add(buildContact(ContactPersonTypeEnumeration.SUPPORT)); + entityDescriptor.getContactPersons().add(buildContact(ContactPersonTypeEnumeration.TECHNICAL)); + entityDescriptor.setValidUntil(getExpireDate()); + + X509KeyInfoGeneratorFactory keyInfoGeneratorFactory = new X509KeyInfoGeneratorFactory(); + keyInfoGeneratorFactory.setEmitEntityCertificate(true); + Extensions e = generateExtensions(); + if (!e.getUnknownXMLObjects().isEmpty()) { + entityDescriptor.setExtensions(e); + } + if (spSSODescriptor != null) { + generateSPSSODescriptor(entityDescriptor, keyInfoGeneratorFactory); + } + if (idpSSODescriptor != null) { + generateIDPSSODescriptor(entityDescriptor, keyInfoGeneratorFactory); + } + if (params.getSpEngine() != null) { + ProtocolEngineI spEngine = params.getSpEngine(); + ((MetadataSignerI) spEngine.getSigner()).signMetadata(entityDescriptor); + } else if (params.getIdpEngine() != null) { + ProtocolEngineI idpEngine = params.getIdpEngine(); + ((MetadataSignerI) idpEngine.getSigner()).signMetadata(entityDescriptor); + } + return EidasStringUtil.toString(OpenSamlHelper.marshall(entityDescriptor, false)); + } catch (Exception ex) { + LOGGER.info("ERROR : SAMLException ", ex.getMessage()); + LOGGER.debug("ERROR : SAMLException ", ex); + throw new IllegalStateException(ex); + } + } + + private void generateSPSSODescriptor(final EntityDescriptor entityDescriptor, + final X509KeyInfoGeneratorFactory keyInfoGeneratorFactory) + throws org.opensaml.xml.security.SecurityException, IllegalAccessException, NoSuchFieldException, + SAMLEngineException, EIDASSAMLEngineException { + //the node has SP role + spSSODescriptor.setWantAssertionsSigned(params.isWantAssertionsSigned()); + spSSODescriptor.setAuthnRequestsSigned(true); + spSSODescriptor.setID(idpSSODescriptor == null ? params.getEntityID() + : ("SP" + params.getEntityID())); + if (params.getSPSignature() != null) { + spSSODescriptor.setSignature(params.getSPSignature()); + } + if (params.getSpSigningCredential() != null) { + spSSODescriptor.getKeyDescriptors() + .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getSpSigningCredential(), UsageType.SIGNING)); + + } else if (params.getSigningCredential() != null) { + spSSODescriptor.getKeyDescriptors() + .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getSigningCredential(), UsageType.SIGNING)); + } + + if (params.getSpEncryptionCredential() != null) { + spSSODescriptor.getKeyDescriptors() + .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getSpEncryptionCredential(), + UsageType.ENCRYPTION)); + } else if (params.getEncryptionCredential() != null) { + spSSODescriptor.getKeyDescriptors() + .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getEncryptionCredential(), UsageType.ENCRYPTION)); + } + spSSODescriptor.addSupportedProtocol(params.getSpSamlProtocol()); + if (!StringUtils.isEmpty(params.getAssertionConsumerUrl())) { + addAssertionConsumerService(); + } + fillNameIDFormat(spSSODescriptor); + if (params.getSpEngine() != null) { + ProtocolEngineI spEngine = params.getSpEngine(); + ((MetadataSignerI) spEngine.getSigner()).signMetadata(spSSODescriptor); + } + entityDescriptor.getRoleDescriptors().add(spSSODescriptor); + + } + + private void fillNameIDFormat(SSODescriptor ssoDescriptor) throws EIDASSAMLEngineException { + NameIDFormat persistentFormat = + (NameIDFormat) BuilderFactoryUtil.buildXmlObject(NameIDFormat.DEFAULT_ELEMENT_NAME); + persistentFormat.setFormat(SamlNameIdFormat.PERSISTENT.getNameIdFormat()); + ssoDescriptor.getNameIDFormats().add(persistentFormat); + NameIDFormat transientFormat = + (NameIDFormat) BuilderFactoryUtil.buildXmlObject(NameIDFormat.DEFAULT_ELEMENT_NAME); + transientFormat.setFormat(SamlNameIdFormat.TRANSIENT.getNameIdFormat()); + ssoDescriptor.getNameIDFormats().add(transientFormat); + NameIDFormat unspecifiedFormat = + (NameIDFormat) BuilderFactoryUtil.buildXmlObject(NameIDFormat.DEFAULT_ELEMENT_NAME); + unspecifiedFormat.setFormat(SamlNameIdFormat.UNSPECIFIED.getNameIdFormat()); + ssoDescriptor.getNameIDFormats().add(unspecifiedFormat); + } + + private void generateIDPSSODescriptor(final EntityDescriptor entityDescriptor, + final X509KeyInfoGeneratorFactory keyInfoGeneratorFactory) + throws org.opensaml.xml.security.SecurityException, IllegalAccessException, NoSuchFieldException, + SAMLEngineException, EIDASSAMLEngineException { + //the node has IDP role + idpSSODescriptor.setWantAuthnRequestsSigned(true); + idpSSODescriptor.setID(spSSODescriptor == null ? params.getEntityID() + : ("IDP" + params.getEntityID())); + if (params.getIDPSignature() != null) { + idpSSODescriptor.setSignature(params.getIDPSignature()); + } + if (params.getIdpSigningCredential() != null) { + idpSSODescriptor.getKeyDescriptors() + .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getIdpSigningCredential(), UsageType.SIGNING)); + } else if (params.getSigningCredential() != null) { + idpSSODescriptor.getKeyDescriptors() + .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getSigningCredential(), UsageType.SIGNING)); + } + if (params.getIdpEncryptionCredential() != null) { + idpSSODescriptor.getKeyDescriptors() + .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getIdpEncryptionCredential(), + UsageType.ENCRYPTION)); + } else if (params.getEncryptionCredential() != null) { + idpSSODescriptor.getKeyDescriptors() + .add(getKeyDescriptor(keyInfoGeneratorFactory, params.getEncryptionCredential(), UsageType.ENCRYPTION)); + } + idpSSODescriptor.addSupportedProtocol(params.getIdpSamlProtocol()); + fillNameIDFormat(idpSSODescriptor); + if (params.getIdpEngine() != null) { + if (params.getIdpEngine().getProtocolProcessor() != null + && params.getIdpEngine().getProtocolProcessor().getFormat() == SAMLExtensionFormat.EIDAS10) { + + /*TODO: Only a work-around to add eIDAS attributes, which could be provided from MOA-ID, to IDP metadata + * If we restrict the eIDAS Engine attribute definitions then also additional incoming attributes can not processed any more. + * + * INFO: Maybe, this code can be removed in a future version of the eIDAS engine + */ + generateSupportedAttributes(idpSSODescriptor, getAllSupportedAttributes()); + } + ProtocolEngineI idpEngine = params.getIdpEngine(); + ((MetadataSignerI) idpEngine.getSigner()).signMetadata(idpSSODescriptor); + } + + idpSSODescriptor.getSingleSignOnServices().addAll(buildSingleSignOnServicesBindingLocations()); + + entityDescriptor.getRoleDescriptors().add(idpSSODescriptor); + + } + + /*TODO: Only a work-around to add eIDAS attributes, which could be provided from MOA-ID, to IDP metadata + * If we restrict the eIDAS Engine attribute definitions then also additional incoming attributes can not processed any more. + */ + public ImmutableSortedSet<AttributeDefinition<?>> getAllSupportedAttributes() { + ImmutableSortedSet.Builder<AttributeDefinition<?>> builder = + new ImmutableSortedSet.Builder<>(Ordering.<AttributeDefinition<?>>natural()); + builder.addAll(Constants.MOA_IDP_ATTR_REGISTRY.getAttributes()); + return builder.build(); + } + + private ArrayList<SingleSignOnService> buildSingleSignOnServicesBindingLocations() + throws NoSuchFieldException, IllegalAccessException { + ArrayList<SingleSignOnService> singleSignOnServices = new ArrayList<SingleSignOnService>(); + + HashMap<String, String> bindingLocations = params.getProtocolBindingLocation(); + for (String binding : bindingLocations.keySet()) { + SingleSignOnService ssos = BuilderFactoryUtil.buildXmlObject(SingleSignOnService.class); + ssos.setBinding(binding); + ssos.setLocation(bindingLocations.get(binding)); + singleSignOnServices.add(ssos); + } + + return singleSignOnServices; + } + + /** + * @param metadata + * @return an EntityDescriptor parsed from the given String or null + */ + // TODO (commented by donydgr) Move to a eu.eidas.auth.engine.metadata.MetadataUtil ? Throw an exception if the metadata is invalid instead of returning null ? + public static EntityDescriptorContainer deserializeEntityDescriptor(String metadata) { + EntityDescriptorContainer result = new EntityDescriptorContainer(); + try { + byte[] metaDataBytes = EidasStringUtil.getBytes(metadata); + XMLObject obj = OpenSamlHelper.unmarshall(metaDataBytes); + if (obj instanceof EntityDescriptor) { + result.addEntityDescriptor((EntityDescriptor) obj, metaDataBytes); + } else if (obj instanceof EntitiesDescriptor) { + EntitiesDescriptor ed = (EntitiesDescriptor) obj; + result.setEntitiesDescriptor(ed); + result.getEntityDescriptors().addAll(((EntitiesDescriptor) obj).getEntityDescriptors()); + result.setSerializedEntitesDescriptor(metaDataBytes); + } + } catch (UnmarshallException ue) { + LOGGER.info("ERROR : unmarshalling error", ue.getMessage()); + LOGGER.debug("ERROR : unmarshalling error", ue); + } + return result; + } + + private KeyDescriptor getKeyDescriptor(X509KeyInfoGeneratorFactory keyInfoGeneratorFactory, + Credential credential, + UsageType usage) + throws NoSuchFieldException, IllegalAccessException, SecurityException, EIDASSAMLEngineException { + KeyDescriptor keyDescriptor = null; + if (credential != null) { + keyDescriptor = BuilderFactoryUtil.buildXmlObject(KeyDescriptor.class); + KeyInfoGenerator keyInfoGenerator = keyInfoGeneratorFactory.newInstance(); + + KeyInfo keyInfo = keyInfoGenerator.generate(credential); + keyDescriptor.setUse(usage); + keyDescriptor.setKeyInfo(keyInfo); + if (usage == UsageType.ENCRYPTION && params.getEncryptionAlgorithms() != null) { + Set<String> encryptionAlgos = EIDASUtil.parseSemicolonSeparatedList(params.getEncryptionAlgorithms()); + for (String encryptionAlgo : encryptionAlgos) { + EncryptionMethod em = + (EncryptionMethod) BuilderFactoryUtil.buildXmlObject(EncryptionMethod.DEFAULT_ELEMENT_NAME); + em.setAlgorithm(encryptionAlgo); + keyDescriptor.getEncryptionMethods().add(em); + } + } + + } + return keyDescriptor; + } + + private Organization buildOrganization() { + Organization organization = null; + try { + organization = BuilderFactoryUtil.buildXmlObject(Organization.class); + OrganizationDisplayName odn = BuilderFactoryUtil.buildXmlObject(OrganizationDisplayName.class); + odn.setName(new LocalizedString(params.getCountryName(), "en")); + organization.getDisplayNames().add(odn); + OrganizationURL url = BuilderFactoryUtil.buildXmlObject(OrganizationURL.class); + url.setURL(new LocalizedString(params.getNodeUrl(), "en")); + organization.getURLs().add(url); + } catch (IllegalAccessException iae) { + LOGGER.info("ERROR : error generating the Organization: {}", iae.getMessage()); + LOGGER.debug("ERROR : error generating the Organization: {}", iae); + } catch (NoSuchFieldException nfe) { + LOGGER.info("ERROR : error generating the Organization: {}", nfe.getMessage()); + LOGGER.debug("ERROR : error generating the Organization: {}", nfe); + } + return organization; + } + + private ContactPerson buildContact(ContactPersonTypeEnumeration contactType) { + ContactPerson contact = null; + try { + Contact currentContact = null; + if (contactType == ContactPersonTypeEnumeration.SUPPORT) { + currentContact = params.getSupportContact(); + } else if (contactType == ContactPersonTypeEnumeration.TECHNICAL) { + currentContact = params.getTechnicalContact(); + } else { + LOGGER.error("ERROR: unsupported contact type"); + } + contact = BuilderFactoryUtil.buildXmlObject(ContactPerson.class); + if (currentContact == null) { + LOGGER.error("ERROR: cannot retrieve contact from the configuration"); + return contact; + } + + EmailAddress emailAddressObj = BuilderFactoryUtil.buildXmlObject(EmailAddress.class); + Company company = BuilderFactoryUtil.buildXmlObject(Company.class); + GivenName givenName = BuilderFactoryUtil.buildXmlObject(GivenName.class); + SurName surName = BuilderFactoryUtil.buildXmlObject(SurName.class); + TelephoneNumber phoneNumber = BuilderFactoryUtil.buildXmlObject(TelephoneNumber.class); + contact.setType(contactType); + emailAddressObj.setAddress(currentContact.getEmail()); + company.setName(currentContact.getCompany()); + givenName.setName(currentContact.getGivenName()); + surName.setName(currentContact.getSurName()); + phoneNumber.setNumber(currentContact.getPhone()); + + populateContact(contact, currentContact, emailAddressObj, company, givenName, surName, phoneNumber); + + } catch (IllegalAccessException iae) { + LOGGER.info("ERROR : error generating the Organization: {}", iae.getMessage()); + LOGGER.debug("ERROR : error generating the Organization: {}", iae); + } catch (NoSuchFieldException nfe) { + LOGGER.info("ERROR : error generating the Organization: {}", nfe.getMessage()); + LOGGER.debug("ERROR : error generating the Organization: {}", nfe); + } + return contact; + } + + private void populateContact(ContactPerson contact, + Contact currentContact, + EmailAddress emailAddressObj, + Company company, + GivenName givenName, + SurName surName, + TelephoneNumber phoneNumber) { + if (!StringUtils.isEmpty(currentContact.getEmail())) { + contact.getEmailAddresses().add(emailAddressObj); + } + if (!StringUtils.isEmpty(currentContact.getCompany())) { + contact.setCompany(company); + } + if (!StringUtils.isEmpty(currentContact.getGivenName())) { + contact.setGivenName(givenName); + } + if (!StringUtils.isEmpty(currentContact.getSurName())) { + contact.setSurName(surName); + } + if (!StringUtils.isEmpty(currentContact.getPhone())) { + contact.getTelephoneNumbers().add(phoneNumber); + } + + } + + /** + * @param engine a EIDASSamlEngine from which signing and encryption information is extracted + */ + + public void initialize(ProtocolEngineI engine) throws EIDASSAMLEngineException { + + X509Certificate decryptionCertificate = engine.getDecryptionCertificate(); + if (null != decryptionCertificate) { + params.setEncryptionCredential(CertificateUtil.toCredential(decryptionCertificate)); + } + params.setSigningCredential(CertificateUtil.toCredential(engine.getSigningCertificate())); + params.setIdpEngine(engine); + params.setSpEngine(engine); + } + + /** + * @param spEngine a EIDASSamlEngine for the + */ + + public void initialize(ProtocolEngineI spEngine, ProtocolEngineI idpEngine) throws EIDASSAMLEngineException { + if (idpEngine != null) { + idpEngine.getProtocolProcessor().configure(); + params.setIdpSigningCredential(CertificateUtil.toCredential(idpEngine.getSigningCertificate())); + + final X509Certificate idpEngineDecryptionCertificate = idpEngine.getDecryptionCertificate(); + if (idpEngineDecryptionCertificate != null) { + params.setIdpEncryptionCredential(CertificateUtil.toCredential(idpEngineDecryptionCertificate)); + } + + } + if (spEngine != null) { + spEngine.getProtocolProcessor().configure(); + params.setSpSigningCredential(CertificateUtil.toCredential(spEngine.getSigningCertificate())); + + final X509Certificate spEngineDecryptionCertificate = spEngine.getDecryptionCertificate(); + if (spEngineDecryptionCertificate != null) { + params.setSpEncryptionCredential(CertificateUtil.toCredential(spEngineDecryptionCertificate)); + } + } + + params.setIdpEngine(idpEngine); + params.setSpEngine(spEngine); + } + + public void addSPRole() throws EIDASSAMLEngineException { + try { + if (spSSODescriptor == null) { + spSSODescriptor = BuilderFactoryUtil.buildXmlObject(SPSSODescriptor.class); + } + } catch (IllegalAccessException iae) { + throw new EIDASSAMLEngineException(iae); + } catch (NoSuchFieldException nsfe) { + throw new EIDASSAMLEngineException(nsfe); + } + } + + public void addIDPRole() throws EIDASSAMLEngineException { + try { + if (idpSSODescriptor == null) { + idpSSODescriptor = BuilderFactoryUtil.buildXmlObject(IDPSSODescriptor.class); + } + } catch (IllegalAccessException iae) { + throw new EIDASSAMLEngineException(iae); + } catch (NoSuchFieldException nsfe) { + throw new EIDASSAMLEngineException(nsfe); + } + } + + private void generateDigest(Extensions eidasExtensions) throws EIDASSAMLEngineException { + if (!StringUtils.isEmpty(params.getDigestMethods())) { + Set<String> signatureMethods = EIDASUtil.parseSemicolonSeparatedList(params.getDigestMethods()); + Set<String> digestMethods = new HashSet<String>(); + for (String signatureMethod : signatureMethods) { + digestMethods.add(CertificateUtil.validateDigestAlgorithm(signatureMethod)); + } + for (String digestMethod : digestMethods) { + final DigestMethod dm = (DigestMethod) BuilderFactoryUtil.buildXmlObject(DigestMethod.DEF_ELEMENT_NAME); + if (dm != null) { + dm.setAlgorithm(digestMethod); + eidasExtensions.getUnknownXMLObjects().add(dm); + } else { + LOGGER.info("BUSINESS EXCEPTION error adding DigestMethod extension"); + } + } + } + + } + + private Extensions generateExtensions() throws EIDASSAMLEngineException { + Extensions eidasExtensions = BuilderFactoryUtil.generateExtension(); + if (params.getAssuranceLevel() != null) { + generateLoA(eidasExtensions); + } + if (!StringUtils.isEmpty(params.getSpType())) { + final SPType spTypeObj = (SPType) BuilderFactoryUtil.buildXmlObject(SPType.DEF_ELEMENT_NAME); + if (spTypeObj != null) { + spTypeObj.setSPType(params.getSpType()); + eidasExtensions.getUnknownXMLObjects().add(spTypeObj); + } else { + LOGGER.info("BUSINESS EXCEPTION error adding SPType extension"); + } + } + generateDigest(eidasExtensions); + + if (!StringUtils.isEmpty(params.getSigningMethods())) { + Set<String> signMethods = EIDASUtil.parseSemicolonSeparatedList(params.getDigestMethods()); + for (String signMethod : signMethods) { + final SigningMethod sm = + (SigningMethod) BuilderFactoryUtil.buildXmlObject(SigningMethod.DEF_ELEMENT_NAME); + if (sm != null) { + sm.setAlgorithm(signMethod); + eidasExtensions.getUnknownXMLObjects().add(sm); + } else { + LOGGER.info("BUSINESS EXCEPTION error adding SigningMethod extension"); + } + } + } + return eidasExtensions; + } + + private void generateLoA(Extensions eidasExtensions) throws EIDASSAMLEngineException { + EntityAttributes loa = + (EntityAttributes) BuilderFactoryUtil.buildXmlObject(EntityAttributes.DEFAULT_ELEMENT_NAME); + Attribute loaAttrib = (Attribute) BuilderFactoryUtil.buildXmlObject(Attribute.DEFAULT_ELEMENT_NAME); + loaAttrib.setName(EidasConstants.LEVEL_OF_ASSURANCE_NAME); + loaAttrib.setNameFormat(Attribute.URI_REFERENCE); + XSStringBuilder stringBuilder = + (XSStringBuilder) Configuration.getBuilderFactory().getBuilder(XSString.TYPE_NAME); + XSString stringValue = stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME); + stringValue.setValue(params.getAssuranceLevel()); + loaAttrib.getAttributeValues().add(stringValue); + loa.getAttributes().add(loaAttrib); + eidasExtensions.getUnknownXMLObjects().add(loa); + + } + + private static final Set<String> DEFAULT_BINDING = new HashSet<String>() {{ + this.add(SAMLConstants.SAML2_POST_BINDING_URI); + }}; + + private void addAssertionConsumerService() throws EIDASSAMLEngineException { + int index = 0; + Set<String> bindings = params.getProtocolBinding().isEmpty() ? DEFAULT_BINDING : params.getProtocolBinding(); + for (String binding : bindings) { + AssertionConsumerService asc = (AssertionConsumerService) BuilderFactoryUtil.buildXmlObject( + AssertionConsumerService.DEFAULT_ELEMENT_NAME); + asc.setLocation(params.getAssertionConsumerUrl()); + asc.setBinding(checkBinding(binding)); + asc.setIndex(index); + if (index == 0) { + asc.setIsDefault(true); + } + index++; + spSSODescriptor.getAssertionConsumerServices().add(asc); + } + } + + private String checkBinding(String binding) { + if (binding != null && (binding.equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI) || binding.equals( + SAMLConstants.SAML2_POST_BINDING_URI))) { + return binding; + } + return SAMLConstants.SAML2_POST_BINDING_URI; + } + + private DateTime getExpireDate() { + DateTime expiryDate = DateTime.now(); + expiryDate = + expiryDate.withFieldAdded(DurationFieldType.seconds(), (int) (getConfigParams().getValidityDuration())); + return expiryDate; + } + + private void generateSupportedAttributes(IDPSSODescriptor idpssoDescriptor, + ImmutableSortedSet<AttributeDefinition<?>> attributeDefinitions) + throws EIDASSAMLEngineException { + List<Attribute> attributes = idpssoDescriptor.getAttributes(); + for (AttributeDefinition<?> attributeDefinition : attributeDefinitions) { + Attribute a = (Attribute) BuilderFactoryUtil.buildXmlObject(Attribute.DEFAULT_ELEMENT_NAME); + a.setName(attributeDefinition.getNameUri().toASCIIString()); + a.setFriendlyName(attributeDefinition.getFriendlyName()); + a.setNameFormat(Attribute.URI_REFERENCE); + attributes.add(a); + } + } + + public MetadataConfigParams getConfigParams() { + return params; + } + + public void setConfigParams(MetadataConfigParams params) { + this.params = params; + } + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java index eeb8305cf..eb50c113f 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java @@ -22,15 +22,27 @@ */ package at.gv.egovernment.moa.id.auth.modules.eidas.utils; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import org.opensaml.xml.ConfigurationException; +import org.opensaml.xml.XMLConfigurator; + import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; import at.gv.egovernment.moa.id.auth.modules.eidas.config.MOAIDCertificateManagerConfigurationImpl; +import at.gv.egovernment.moa.id.auth.modules.eidas.config.MOASWSigner; +import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAEidasProtocolProcesser; import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASMetadataProviderDecorator; -import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDAsExtensionProcessor; import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; import at.gv.egovernment.moa.logging.Logger; -import eu.eidas.auth.engine.EIDASSAMLEngine; -import eu.eidas.auth.engine.core.ExtensionProcessorI; +import eu.eidas.auth.commons.attribute.AttributeDefinition; +import eu.eidas.auth.engine.ProtocolEngineI; +import eu.eidas.auth.engine.SamlEngineSystemClock; +import eu.eidas.auth.engine.metadata.MetadataFetcherI; +import eu.eidas.auth.engine.metadata.MetadataSignerI; +import eu.eidas.auth.engine.xml.opensaml.SAMLBootstrap; import eu.eidas.engine.exceptions.EIDASSAMLEngineException; import eu.eidas.samlengineconfig.CertificateConfigurationManager; @@ -40,31 +52,44 @@ import eu.eidas.samlengineconfig.CertificateConfigurationManager; */ public class SAMLEngineUtils { - private static EIDASSAMLEngine eIDASEngine = null; + private static ProtocolEngineI eIDASEngine = null; + private static MetadataSignerI metadataSigner = null; + private static MetadataFetcherI metadataFetcher = null; + private static Map<String, AttributeDefinition<?>> allSupportedAttributeMap = + new HashMap<String, AttributeDefinition<?>>(); - public static synchronized EIDASSAMLEngine createSAMLEngine() throws EIDASEngineException{ + public static synchronized ProtocolEngineI createSAMLEngine(MOAeIDASChainingMetadataProvider moaeIDASMetadataProvider) throws EIDASEngineException{ if (eIDASEngine == null) { try { //get eIDAS SAMLengine configuration from MOA-ID configuration CertificateConfigurationManager configManager = new MOAIDCertificateManagerConfigurationImpl(); + + //set metadata management to eIDAS SAMLengine + metadataFetcher = new MOAeIDASMetadataProviderDecorator(moaeIDASMetadataProvider); + + //set metadata signer + metadataSigner = new MOASWSigner(configManager); + + //build eIDAS SAML eninge + ProtocolEngineI engine = MOAProtocolEngineFactory.createProtocolEngine( + Constants.eIDAS_SAML_ENGINE_NAME, + configManager, + new MOAEidasProtocolProcesser(metadataFetcher, metadataSigner), + new SamlEngineSystemClock()); + + //build a map with all actually supported attributes + for (AttributeDefinition<?> el : engine.getProtocolProcessor().getAllSupportedAttributes()) + allSupportedAttributeMap.put(el.getFriendlyName(), el); + + //TODO: check if bug is fixed in next eIDAS SAML-engine version + //overwrite eIDAS response validator suite because Condition-Valitator has not time jitter + initOpenSAMLConfig("own-saml-eidasnode-config.xml"); - //initial eIDAS SAMLengine - EIDASSAMLEngine engine = EIDASSAMLEngine.createSAMLEngine(Constants.eIDAS_SAML_ENGINE_NAME, - configManager); - - //set metadata management to eIDAS SAMLengine - engine.setMetadataProcessor( - new MOAeIDASMetadataProviderDecorator( - MOAeIDASChainingMetadataProvider.getInstance())); - - //set MOA specific extension processor - ExtensionProcessorI extensionProcessor = new MOAeIDAsExtensionProcessor(); - engine.setExtensionProcessor(extensionProcessor); eIDASEngine = engine; - } catch (EIDASSAMLEngineException e) { + } catch (EIDASSAMLEngineException | ConfigurationException e) { Logger.error("eIDAS SAMLengine initialization FAILED!", e); throw new EIDASEngineException("eIDAS.00", new Object[]{e.getMessage()}, e); @@ -73,5 +98,51 @@ public class SAMLEngineUtils { return eIDASEngine; } + + /** + * Get a map of all eIDAS attributes, which are actually supported by eIDAS engine + * + * @return Map<Attr. FriendlyName, AttributeDefinition> + */ + public static Map<String, AttributeDefinition<?>> getMapOfAllAvailableAttributes() { + return allSupportedAttributeMap; + + } + + /** + * @return the metadataSigner + */ + public static MetadataSignerI getMetadataSigner() { + if (eIDASEngine != null) + return metadataSigner; + + else { + Logger.error("eIDAS SAMLEngine is not initialized."); + return null; + + } + } + + /** + * @return the metadataFetcher + */ + public static MetadataFetcherI getMetadataFetcher() { + if (eIDASEngine != null) + return metadataFetcher; + + else { + Logger.error("eIDAS SAMLEngine is not initialized."); + return null; + + } + } + + private static void initOpenSAMLConfig(String xmlConfig) throws ConfigurationException { + XMLConfigurator configurator = new XMLConfigurator(); + InputStream is = SAMLBootstrap.class.getClassLoader().getResourceAsStream(xmlConfig); + configurator.load(is); + + } + } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SimpleEidasAttributeGenerator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SimpleEidasAttributeGenerator.java new file mode 100644 index 000000000..d43fa1622 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SimpleEidasAttributeGenerator.java @@ -0,0 +1,68 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.eidas.utils; + +import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator; + +/** + * @author tlenz + * + */ +public class SimpleEidasAttributeGenerator implements IAttributeGenerator<String> { + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator#buildStringAttribute(java.lang.String, java.lang.String, java.lang.String) + */ + @Override + public String buildStringAttribute(String friendlyName, String name, String value) { + return value; + + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator#buildIntegerAttribute(java.lang.String, java.lang.String, int) + */ + @Override + public String buildIntegerAttribute(String friendlyName, String name, int value) { + return String.valueOf(value); + + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator#buildLongAttribute(java.lang.String, java.lang.String, long) + */ + @Override + public String buildLongAttribute(String friendlyName, String name, long value) { + return String.valueOf(value); + + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator#buildEmptyAttribute(java.lang.String, java.lang.String) + */ + @Override + public String buildEmptyAttribute(String friendlyName, String name) { + return null; + } + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java index 563c3a18c..7647b4cab 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java @@ -2,13 +2,14 @@ package at.gv.egovernment.moa.id.protocols.eidas; import java.util.Collection; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; -import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAPersonalAttributeList; import at.gv.egovernment.moa.id.moduls.RequestImpl; -import eu.eidas.auth.commons.EIDASAuthnRequest; +import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; +import eu.eidas.auth.commons.protocol.IAuthenticationRequest; @Component("EIDASData") @Scope(value = BeanDefinition.SCOPE_PROTOTYPE) @@ -18,10 +19,10 @@ public class EIDASData extends RequestImpl { private static final long serialVersionUID = 8765755670214923910L; /** The attributes requested by the eIDaS. */ - private MOAPersonalAttributeList attributes; + private ImmutableAttributeMap attributes; /** The incoming eIDaS SAML2 AuthnRequest. */ - private EIDASAuthnRequest authnRequest; + private IAuthenticationRequest authnRequest; /** The ip address of the requester. */ private String remoteIPAddress; @@ -29,7 +30,7 @@ public class EIDASData extends RequestImpl { private String remoteRelayState; @Override - public Collection<String> getRequestedAttributes() { + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider) { // TODO Auto-generated method stub return null; } @@ -39,17 +40,17 @@ public class EIDASData extends RequestImpl { * * @return the requested attributes */ - public MOAPersonalAttributeList getEidasRequestedAttributes() { - return (MOAPersonalAttributeList) attributes.clone(); + public ImmutableAttributeMap getEidasRequestedAttributes() { + return attributes; } /** * Sets the eidas requested attributes. * - * @param personalAttributeList the requested attributes + * @param immutableAttributeMap the requested attributes */ - public void setEidasRequestedAttributes(MOAPersonalAttributeList personalAttributeList) { - attributes = personalAttributeList; + public void setEidasRequestedAttributes(ImmutableAttributeMap immutableAttributeMap) { + attributes = immutableAttributeMap; } /** @@ -57,7 +58,7 @@ public class EIDASData extends RequestImpl { * * @return the eidas request */ - public EIDASAuthnRequest getEidasRequest() { + public IAuthenticationRequest getEidasRequest() { return authnRequest; } @@ -66,7 +67,7 @@ public class EIDASData extends RequestImpl { * * @param request the new eidas request */ - public void setEidasRequest(EIDASAuthnRequest request) { + public void setEidasRequest(IAuthenticationRequest request) { authnRequest = request; } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java index 779d898be..13e64cdd0 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java @@ -34,6 +34,8 @@ import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.opensaml.saml2.core.StatusCode; import org.opensaml.saml2.metadata.AssertionConsumerService; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @@ -44,11 +46,11 @@ import at.gv.egovernment.moa.id.auth.frontend.velocity.VelocityProvider; 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.engine.MOAeIDASMetadataProviderDecorator; -import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASAuthnRequestProcessingException; -import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASAuthnRequestValidationException; -import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASException; -import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAPersonalAttributeList; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASAuthnRequestProcessingException; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASAuthnRequestValidationException; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASException; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; +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.exceptions.MOAIDException; @@ -56,10 +58,14 @@ import at.gv.egovernment.moa.id.moduls.RequestImpl; import at.gv.egovernment.moa.id.protocols.AbstractAuthProtocolModulController; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; -import eu.eidas.auth.commons.EIDASAuthnRequest; -import eu.eidas.auth.commons.EIDASAuthnResponse; -import eu.eidas.auth.commons.EIDASUtil; -import eu.eidas.auth.engine.EIDASSAMLEngine; +import eu.eidas.auth.commons.EidasStringUtil; +import eu.eidas.auth.commons.protocol.IAuthenticationRequest; +import eu.eidas.auth.commons.protocol.IResponseMessage; +import eu.eidas.auth.commons.protocol.eidas.IEidasAuthenticationRequest; +import eu.eidas.auth.commons.protocol.eidas.impl.EidasAuthenticationRequest; +import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse; +import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse.Builder; +import eu.eidas.auth.engine.ProtocolEngineI; import eu.eidas.auth.engine.metadata.MetadataUtil; import eu.eidas.engine.exceptions.EIDASSAMLEngineException; @@ -72,14 +78,17 @@ import eu.eidas.engine.exceptions.EIDASSAMLEngineException; public class EIDASProtocol extends AbstractAuthProtocolModulController { public static final String NAME = EIDASProtocol.class.getName(); - public static final String PATH = "eidas"; + public static final String PATH = "eidas"; + @Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider; + public EIDASProtocol() { super(); Logger.debug("Registering servlet " + getClass().getName() + " with mappings '" + Constants.eIDAS_HTTP_ENDPOINT_METADATA + "' and '" + Constants.eIDAS_HTTP_ENDPOINT_IDP_COLLEAGUEREQUEST + - "' and '" + Constants.eIDAS_HTTP_ENDPOINT_IDP_POST +"'."); + //"' and '" + Constants.eIDAS_HTTP_ENDPOINT_IDP_POST + + "'."); } @@ -164,75 +173,139 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { String base64SamlToken = request.getParameter("SAMLRequest"); if (MiscUtil.isEmpty(base64SamlToken)) { Logger.warn("No eIDAS SAMLRequest found in http request."); - throw new MOAIDException("HTTP request includes no eIDAS SAML-Request element.", null); + throw new MOAIDException("eIDAS.06", new Object[]{"HTTP request includes no eIDAS SAML-Request element."}); } - byte[] decSamlToken = EIDASUtil.decodeSAMLToken(base64SamlToken); - + try { + //decode SAML2 token + byte[] decSamlToken = EidasStringUtil.decodeBytesFromBase64(base64SamlToken); + //get eIDAS SAML-engine - EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); - - //validate SAML token - EIDASAuthnRequest samlReq = engine.validateEIDASAuthnRequest(decSamlToken); - - // - memorize remote ip - pendingReq.setRemoteAddress(request.getRemoteAddr()); + ProtocolEngineI engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); - // - memorize relaystate - String relayState = request.getParameter("RelayState"); - pendingReq.setRemoteRelayState(relayState); - - // - memorize country code of target country - pendingReq.setGenericDataToSession( - RequestImpl.eIDAS_GENERIC_REQ_DATA_COUNTRY, samlReq.getCountry()); + String cititzenCountryCode = + authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, + MOAIDAuthConstants.COUNTRYCODE_AUSTRIA); - // - memorize requested attributes - pendingReq.setEidasRequestedAttributes(new MOAPersonalAttributeList(samlReq.getPersonalAttributeList())); + + //**************************************** + //***** validate eIDAS request ********* + //**************************************** + //validate SAML token + IAuthenticationRequest samlReq = engine.unmarshallRequestAndValidate(decSamlToken, cititzenCountryCode ); - // - memorize whole request - samlReq.setPersonalAttributeList(pendingReq.getEidasRequestedAttributes()); // circumvent non-serializable eidas personal attribute list - pendingReq.setEidasRequest(samlReq); + //validate internal JAVA class type + if (!(samlReq instanceof IEidasAuthenticationRequest)) { + Logger.error("eIDAS AuthnRequst from node:" + samlReq.getIssuer() + + " is NOT from Type:" + IEidasAuthenticationRequest.class.getName()); + throw new MOAIDException("eIDAS.06", new Object[]{"eIDAS AuthnRequest maps to an wrong internal Type."}); + + } + IEidasAuthenticationRequest eIDASSamlReq = (IEidasAuthenticationRequest) samlReq; + + //validate Destination against MOA-ID-Auth configuration + String reqDestination = eIDASSamlReq.getDestination(); + if (MiscUtil.isEmpty(reqDestination) || + !reqDestination.startsWith(pendingReq.getAuthURL())) { + Logger.info("eIDAS AuthnRequest contains a not valid 'Destination' attribute"); + throw new EIDASAuthnRequestValidationException("stork.01", + new Object[]{"eIDAS AuthnRequest contains a not valid 'Destination' attribute"}); + + } + + //validate AssertionConsumerServiceURL against metadata + EntityDescriptor eIDASNodeEntityDesc = new MOAeIDASMetadataProviderDecorator(eIDASMetadataProvider) + .getEntityDescriptor(eIDASSamlReq.getIssuer(), SAMLEngineUtils.getMetadataSigner()); - //validate destination against metadata - String reqDestination = samlReq.getDestination(); - if (MiscUtil.isNotEmpty(reqDestination)) { - boolean isValid = false; - List<AssertionConsumerService> allowedAssertionConsumerUrl = new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()) - .getSPSSODescriptor(samlReq.getIssuer()).getAssertionConsumerServices(); + String reqAssertionConsumerServiceURL = eIDASSamlReq.getAssertionConsumerServiceURL(); + if (MiscUtil.isNotEmpty(reqAssertionConsumerServiceURL)) { + boolean isValid = false; + List<AssertionConsumerService> allowedAssertionConsumerUrl = + MetadataUtil.getSPSSODescriptor(eIDASNodeEntityDesc).getAssertionConsumerServices(); for (AssertionConsumerService el : allowedAssertionConsumerUrl) { - if (reqDestination.equals(el.getLocation())) + if (reqAssertionConsumerServiceURL.equals(el.getLocation())) isValid = true; } if (!isValid) { - Logger.info("eIDAS AuthnRequest contains a not valid 'Destination' attribute"); - throw new eIDASAuthnRequestValidationException("stork.01", - new Object[]{"eIDAS AuthnRequest contains a not valid 'Destination' attribute"}); + Logger.info("eIDAS AuthnRequest contains a not valid 'AssertionConsumerServiceURL' attribute"); + throw new EIDASAuthnRequestValidationException("eIDAS.12", + new Object[]{"eIDAS AuthnRequest contains a not valid 'AssertionConsumerServiceURL' attribute"}); } - } + } else { + /*TODO: eIDAS SAMLEngine 1.1.0 does not validate and set AssertionConsumerServiceURL in a correct form + * + * Actually, this step is required because EidasProtocolProcesser.class only use the AssertionConsumerServiceURL + * from AuthnRequest to set the 'Destination' attribute in eIDAS Response. However, the AssertionConsumerServiceURL + * could be empty in Request, which break the Response building process. + */ + String assertionConsumerServiceURL = MetadataUtil.getAssertionConsumerUrlFromMetadata( + SAMLEngineUtils.getMetadataFetcher(), SAMLEngineUtils.getMetadataSigner(), eIDASSamlReq); + if (MiscUtil.isEmpty(assertionConsumerServiceURL)) { + Logger.error("eIDAS metadata for node:" + eIDASSamlReq.getIssuer() + + " contains NO 'AssertionConsumerServiceURL' element!"); + throw new EIDASSAMLEngineException("eIDAS metadata for node:" + eIDASSamlReq.getIssuer() + + " contains NO 'AssertionConsumerServiceURL' element!"); + + } + + EidasAuthenticationRequest.Builder test = EidasAuthenticationRequest.builder(eIDASSamlReq); + test.assertionConsumerServiceURL(assertionConsumerServiceURL); + eIDASSamlReq = test.build(); + + } + + //************************************************* + //***** store eIDAS request information ********* + //************************************************* + // - memorize remote ip + pendingReq.setRemoteAddress(request.getRemoteAddr()); + + // - memorize relaystate + String relayState = request.getParameter("RelayState"); + pendingReq.setRemoteRelayState(relayState); + + // - memorize country code of target country + pendingReq.setGenericDataToSession( + RequestImpl.eIDAS_GENERIC_REQ_DATA_COUNTRY, samlReq.getOriginCountryCode()); + + //store level of assurance + pendingReq.setGenericDataToSession(RequestImpl.eIDAS_GENERIC_REQ_DATA_LEVELOFASSURENCE, + eIDASSamlReq.getEidasLevelOfAssurance().stringValue()); + + // - memorize requested attributes + pendingReq.setEidasRequestedAttributes(eIDASSamlReq.getRequestedAttributes()); + + // - memorize whole request + pendingReq.setEidasRequest(eIDASSamlReq); + // - memorize OA url pendingReq.setOAURL(samlReq.getIssuer()); // - memorize OA config IOAAuthParameters oaConfig = authConfig.getOnlineApplicationParameter(pendingReq.getOAURL()); if (oaConfig == null) - throw new eIDASAuthnRequestProcessingException("eIDAS.08", new Object[]{pendingReq.getOAURL()}); + throw new EIDASAuthnRequestProcessingException("eIDAS.08", new Object[]{pendingReq.getOAURL()}); pendingReq.setOnlineApplicationConfiguration(oaConfig); - - String spType = samlReq.getSPType(); - if (MiscUtil.isEmpty(spType)) { - Logger.info("Load SPType from metadata ... IS NOT IMPLEMENTED YET!!!"); - //TODO: maybe implement this if required + + // - memorize service-provider type from eIDAS request + String spType = null; + if (eIDASSamlReq.getSpType() != null) + spType = eIDASSamlReq.getSpType().getValue(); + + if (MiscUtil.isEmpty(spType)) + spType = MetadataUtil.getSPTypeFromMetadata(eIDASNodeEntityDesc); - } - - Logger.debug("eIDAS request has SPType:" + spType); + if (MiscUtil.isEmpty(spType)) + Logger.debug("eIDAS request has SPType:" + spType); + else + Logger.info("eIDAS request and eIDAS metadata contains NO 'SPType' element."); } catch (MOAIDException e) { Logger.info("eIDAS AuthnRequest preProcessing FAILED. Msg:" + e.getMessage()); @@ -240,11 +313,11 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { } catch (EIDASSAMLEngineException e) { Logger.info("eIDAS AuthnRequest preProcessing FAILED. Msg:" + e.getMessage()); - throw new eIDASAuthnRequestProcessingException("eIDAS.06", new Object[]{e.getMessage()}, e); + throw new EIDASAuthnRequestProcessingException("eIDAS.06", new Object[]{e.getMessage()}, e); } catch(Exception e) { Logger.warn("eIDAS AuthnRequest preProcessing FAILED. Msg:" + e.getMessage(), e); - throw new eIDASAuthnRequestProcessingException("eIDAS.06", new Object[]{e.getMessage()}, e); + throw new EIDASAuthnRequestProcessingException("eIDAS.06", new Object[]{e.getMessage()}, e); } } @@ -258,43 +331,40 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { } try { - EIDASAuthnResponse eIDASResp = new EIDASAuthnResponse(); - eIDASResp.setIssuer(pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_METADATA); - - if (e instanceof eIDASException) { - eIDASResp.setStatusCode(((eIDASException) e).getStatusCodeFirstLevel()); - eIDASResp.setSubStatusCode(((eIDASException) e).getStatusCodeSecondLevel()); - eIDASResp.setMessage(e.getMessage()); + Builder eIDASRespBuilder = new AuthenticationResponse.Builder(); + eIDASRespBuilder.issuer(pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_METADATA); + + if (e instanceof EIDASException) { + eIDASRespBuilder.statusCode(((EIDASException) e).getStatusCodeFirstLevel()); + eIDASRespBuilder.subStatusCode(((EIDASException) e).getStatusCodeSecondLevel()); + eIDASRespBuilder.statusMessage(e.getMessage()); } else if (e instanceof MOAIDException ) { - eIDASResp.setStatusCode(StatusCode.RESPONDER_URI); - eIDASResp.setSubStatusCode(StatusCode.AUTHN_FAILED_URI); - eIDASResp.setMessage(e.getMessage()); + eIDASRespBuilder.statusCode(StatusCode.RESPONDER_URI); + eIDASRespBuilder.subStatusCode(StatusCode.AUTHN_FAILED_URI); + eIDASRespBuilder.statusMessage(e.getMessage()); } else { - eIDASResp.setStatusCode(StatusCode.RESPONDER_URI); - eIDASResp.setSubStatusCode(StatusCode.AUTHN_FAILED_URI); - eIDASResp.setMessage(e.getMessage()); + eIDASRespBuilder.statusCode(StatusCode.RESPONDER_URI); + eIDASRespBuilder.subStatusCode(StatusCode.AUTHN_FAILED_URI); + eIDASRespBuilder.statusMessage(e.getMessage()); } - + + eIDASRespBuilder.id(eu.eidas.auth.engine.xml.opensaml.SAMLEngineUtils.generateNCName()); + eIDASRespBuilder.inResponseTo(eidasReq.getEidasRequest().getId()); - EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); + //build response + AuthenticationResponse eIDASResp = eIDASRespBuilder.build(); - if(null == eidasReq.getEidasRequest().getAssertionConsumerServiceURL()) { - String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata( - new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()), - engine, - eidasReq.getEidasRequest()); - eidasReq.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl); - - } //get eIDAS SAML-engine + ProtocolEngineI engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); + + //build response message + IResponseMessage eIDASRespMsg = engine.generateResponseErrorMessage(eidasReq.getEidasRequest(),eIDASResp, eidasReq.getRemoteAddress()); - eIDASResp = engine.generateEIDASAuthnResponseFail(eidasReq.getEidasRequest(), eIDASResp, - eidasReq.getRemoteAddress(), true); - String token = EIDASUtil.encodeSAMLToken(eIDASResp.getTokenSaml()); + String token = EidasStringUtil.encodeToBase64(eIDASRespMsg.getMessageBytes()); VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine(); Template template = velocityEngine.getTemplate("/resources/templates/stork2_postbinding_template.html"); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java index b4db5c83d..174fa2c17 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java @@ -21,14 +21,20 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.metadata.ContactPerson; import org.opensaml.saml2.metadata.Organization; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; 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.utils.MOAeIDASMetadataGenerator; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; +import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.api.IRequest; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; @@ -37,11 +43,10 @@ import at.gv.egovernment.moa.id.data.SLOInformationInterface; import at.gv.egovernment.moa.id.moduls.IAction; import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; import at.gv.egovernment.moa.logging.Logger; -import eu.eidas.auth.engine.EIDASSAMLEngine; +import eu.eidas.auth.engine.ProtocolEngineI; import eu.eidas.auth.engine.metadata.Contact; import eu.eidas.auth.engine.metadata.MetadataConfigParams; -import eu.eidas.auth.engine.metadata.MetadataGenerator; -import eu.eidas.engine.exceptions.SAMLEngineException; +import eu.eidas.engine.exceptions.EIDASSAMLEngineException; /** @@ -50,6 +55,9 @@ import eu.eidas.engine.exceptions.SAMLEngineException; @Service("EidasMetaDataRequest") public class EidasMetaDataRequest implements IAction { + @Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider; + @Autowired(required=true) AuthConfiguration authConfig; + /* (non-Javadoc) * @see at.gv.egovernment.moa.id.moduls.IAction#processRequest(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.data.IAuthData) */ @@ -61,10 +69,10 @@ public class EidasMetaDataRequest implements IAction { try { String pubURLPrefix = req.getAuthURL(); - String metadata_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_METADATA; + String metadata_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_METADATA; + String sp_return_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_SP_POST; - String sp_return_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_SP_POST; - String metaData = generateMetadata(metadata_url, sp_return_url); + String metaData = generateMetadata(req, metadata_url, sp_return_url); Logger.trace(metaData); @@ -100,24 +108,30 @@ public class EidasMetaDataRequest implements IAction { } - public String generateMetadata(String metadata_url, String sp_return_url) throws SAMLEngineException, EIDASEngineException{ + public String generateMetadata(IRequest pendingReq, String metadata_url, String sp_return_url) throws EIDASSAMLEngineException, EIDASEngineException{ String metadata="invalid metadata"; - EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); + ProtocolEngineI engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); - MetadataGenerator generator = new MetadataGenerator(); + MOAeIDASMetadataGenerator generator = new MOAeIDASMetadataGenerator(); MetadataConfigParams mcp=new MetadataConfigParams(); generator.setConfigParams(mcp); generator.initialize(engine); mcp.setEntityID(metadata_url); mcp.setAssertionConsumerUrl(sp_return_url); + mcp.getProtocolBindingLocation().put( + SAMLConstants.SAML2_POST_BINDING_URI, + pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_IDP_COLLEAGUEREQUEST); //TODO: make it configurable mcp.setAuthnRequestsSigned(true); mcp.setWantAssertionsSigned(true); - mcp.setAssuranceLevel("http://eidas.europa.eu/LoA/substantial"); + mcp.setAssuranceLevel( + authConfig.getBasicMOAIDConfiguration( + Constants.CONIG_PROPS_EIDAS_NODE_LoA, + MOAIDAuthConstants.eIDAS_LOA_HIGH)); //must be set in request, because it could be different for every online-application //mcp.setSpType(SPType.DEFAULT_VALUE); @@ -133,18 +147,24 @@ public class EidasMetaDataRequest implements IAction { Contact technicalContact = new Contact(); List<ContactPerson> contacts = PVPConfiguration.getInstance().getIDPContacts(); - if (contacts != null && contacts.size() >= 1) { - technicalContact.setEmail(contacts.get(0).getEmailAddresses().get(0).getAddress()); - technicalContact.setGivenName(contacts.get(0).getGivenName().getName()); - technicalContact.setSurName(contacts.get(0).getSurName().getName()); - technicalContact.setPhone(contacts.get(0).getTelephoneNumbers().get(0).getNumber()); + if (contacts != null && contacts.size() >= 1) { + ContactPerson contact = contacts.get(0); + technicalContact.setGivenName(contact.getGivenName().getName()); + technicalContact.setSurName(contact.getSurName().getName()); + + if (!contact.getEmailAddresses().isEmpty()) + technicalContact.setEmail(contact.getEmailAddresses().get(0).getAddress()); + + if (!contact.getTelephoneNumbers().isEmpty()) + technicalContact.setPhone(contact.getTelephoneNumbers().get(0).getNumber()); + mcp.setTechnicalContact(technicalContact ); } if (pvpOrganisation != null) { mcp.setNodeUrl(pvpOrganisation.getURLs().get(0).getURL().getLocalString()); - mcp.setCountryName("Austria"); + mcp.setCountryName(authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRY, "Austria")); technicalContact.setCompany(pvpOrganisation.getDisplayNames().get(0).getName().getLocalString()); } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java index ebd4e1e6d..22ac37604 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java @@ -23,8 +23,8 @@ package at.gv.egovernment.moa.id.protocols.eidas; import java.io.StringWriter; +import java.security.MessageDigest; import java.text.SimpleDateFormat; -import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -32,29 +32,44 @@ import javax.servlet.http.HttpServletResponse; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; +import org.opensaml.saml2.core.StatusCode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; +import com.google.common.collect.ImmutableSet; + import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; import at.gv.egovernment.moa.id.auth.frontend.velocity.VelocityProvider; 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.engine.MOAeIDASMetadataProviderDecorator; -import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAPersonalAttributeList; -import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SimpleEidasAttributeGenerator; import at.gv.egovernment.moa.id.commons.api.IRequest; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.data.IAuthData; +import at.gv.egovernment.moa.id.data.SLOInformationImpl; import at.gv.egovernment.moa.id.data.SLOInformationInterface; import at.gv.egovernment.moa.id.moduls.IAction; +import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator; +import at.gv.egovernment.moa.id.protocols.builder.attributes.MandateLegalPersonFullNameAttributeBuilder; +import at.gv.egovernment.moa.id.protocols.builder.attributes.MandateLegalPersonSourcePinAttributeBuilder; +import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException; +import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.logging.Logger; -import eu.eidas.auth.commons.EIDASAuthnResponse; -import eu.eidas.auth.commons.EIDASStatusCode; -import eu.eidas.auth.commons.EIDASUtil; -import eu.eidas.auth.commons.PersonalAttribute; -import eu.eidas.auth.engine.EIDASSAMLEngine; -import eu.eidas.auth.engine.metadata.MetadataUtil; +import at.gv.egovernment.moa.util.Base64Utils; +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.attribute.AttributeValue; +import eu.eidas.auth.commons.attribute.AttributeValueMarshaller; +import eu.eidas.auth.commons.attribute.AttributeValueMarshallingException; +import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; +import eu.eidas.auth.commons.protocol.IResponseMessage; +import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse; +import eu.eidas.auth.commons.protocol.impl.SamlNameIdFormat; +import eu.eidas.auth.engine.ProtocolEngineI; +import eu.eidas.auth.engine.xml.opensaml.SAMLEngineUtils; /** @@ -67,7 +82,10 @@ import eu.eidas.auth.engine.metadata.MetadataUtil; @Service("eIDASAuthenticationRequest") public class eIDASAuthenticationRequest implements IAction { + private static IAttributeGenerator<String> generator = new SimpleEidasAttributeGenerator(); + @Autowired protected MOAReversionLogger revisionsLogger; + @Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider; @Override public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException { @@ -78,67 +96,136 @@ public class eIDASAuthenticationRequest implements IAction { throw new MOAIDException("got wrong IRequest type. is: {}, should be: {}", new String[] {req.getClass().toString(), EIDASData.class.toString()}); - // gather attributes - MOAPersonalAttributeList resultingAttributeList = (MOAPersonalAttributeList) eidasRequest.getEidasRequestedAttributes().clone(); + String subjectNameID = null; - for(Entry<String, PersonalAttribute> current : resultingAttributeList.entrySet()) { + //gather attributes + ImmutableAttributeMap reqAttributeList = (ImmutableAttributeMap) eidasRequest.getEidasRequestedAttributes(); + ImmutableAttributeMap.Builder attrMapBuilder = ImmutableAttributeMap.builder(); + + //TODO: if we support more then this minimum required attributes -> redesign to a smoother attribute builder selector + for(AttributeDefinition<?> attr : reqAttributeList.getDefinitions()) { String newValue = ""; - - // TODO make use of proper builder - switch(current.getKey()) { - case Constants.eIDAS_ATTR_DATEOFBIRTH: newValue = new SimpleDateFormat("YYYY-MM-dd").format(authData.getDateOfBirth()); break; - case Constants.eIDAS_ATTR_CURRENTFAMILYNAME: newValue = authData.getFamilyName();break; - case Constants.eIDAS_ATTR_CURRENTGIVENNAME: newValue = authData.getGivenName();break; - - //TODO: change bPK builder !!!!!! - case Constants.eIDAS_ATTR_PERSONALIDENTIFIER: newValue = authData.getBPK(); break; + boolean isUniqueID = false; + try { + switch(attr.getFriendlyName()) { + case Constants.eIDAS_ATTR_DATEOFBIRTH: + newValue = new SimpleDateFormat("YYYY-MM-dd").format(authData.getDateOfBirth()); + break; + case Constants.eIDAS_ATTR_CURRENTFAMILYNAME: + newValue = authData.getFamilyName(); + break; + case Constants.eIDAS_ATTR_CURRENTGIVENNAME: + newValue = authData.getGivenName(); + break; + case Constants.eIDAS_ATTR_PERSONALIDENTIFIER: + newValue = authData.getBPK(); + isUniqueID = true; + + //generate a transient unique identifier if it is requested + String reqNameIDFormat = eidasRequest.getEidasRequest().getNameIdFormat(); + if (MiscUtil.isNotEmpty(reqNameIDFormat) + && reqNameIDFormat.equals(SamlNameIdFormat.TRANSIENT.getNameIdFormat())) + newValue = generateTransientNameID(newValue); + + subjectNameID = newValue; + break; + case Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER: + newValue = new MandateLegalPersonSourcePinAttributeBuilder().build( + req.getOnlineApplicationConfiguration(), authData, generator); + break; + case Constants.eIDAS_ATTR_LEGALNAME: + newValue = new MandateLegalPersonFullNameAttributeBuilder().build( + req.getOnlineApplicationConfiguration(), authData, generator); + break; + + } + + } catch (AttributeException e) { + Logger.debug("Attribute can not generate requested attribute:" + attr.getFriendlyName() + " Reason:" + e.getMessage()); + } - - if("".equals(newValue)) - current.getValue().setStatus(EIDASStatusCode.STATUS_NOT_AVAILABLE.toString()); - else { - current.getValue().getValue().clear(); - current.getValue().getValue().add(newValue); - current.getValue().setStatus(EIDASStatusCode.STATUS_AVAILABLE.toString()); + + if(MiscUtil.isEmpty(newValue)) { + Logger.info("eIDAS Attr:" + attr.getNameUri() + " is not available."); + + } else { + //set uniqueIdentifier attribute, because eIDAS SAMLEngine use this flag to select the + // Subject->NameID value from this attribute + Builder<?> attrBuilder = AttributeDefinition.builder(attr); + attrBuilder.uniqueIdentifier(isUniqueID); + AttributeDefinition<?> returnAttr = attrBuilder.build(); + + //unmarshal attribute value into eIDAS attribute + AttributeValueMarshaller<?> attributeValueMarshaller = returnAttr.getAttributeValueMarshaller(); + ImmutableSet.Builder<AttributeValue<?>> builder = ImmutableSet.builder(); + + AttributeValue<?> attributeValue = null; + try { + attributeValue = attributeValueMarshaller.unmarshal(newValue, false); + builder.add(attributeValue); + + } catch (AttributeValueMarshallingException e) { + throw new IllegalStateException(e); + + } + + //add attribute to Map + attrMapBuilder.put((AttributeDefinition)returnAttr, (ImmutableSet) builder.build()); + } } // construct eIDaS response - EIDASAuthnResponse response = new EIDASAuthnResponse(); - response.setPersonalAttributeList(resultingAttributeList); + AuthenticationResponse.Builder responseBuilder = new AuthenticationResponse.Builder(); + + responseBuilder.id(SAMLEngineUtils.generateNCName()); + responseBuilder.inResponseTo(eidasRequest.getEidasRequest().getId()); - // - create metadata url - String pubURLPrefix = req.getAuthURL(); + String pubURLPrefix = req.getAuthURL(); String metadata_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_METADATA; - response.setIssuer(metadata_url); - - response.setAssuranceLevel(authData.getEIDASQAALevel()); + responseBuilder.issuer(metadata_url); + + responseBuilder.levelOfAssurance(authData.getEIDASQAALevel()); + + //add attributes + responseBuilder.attributes(attrMapBuilder.build()); + + //set success statuscode + responseBuilder.statusCode(StatusCode.SUCCESS_URI); + + //build response + AuthenticationResponse response = responseBuilder.build(); String token = null; + IResponseMessage eIDASRespMsg = null; try { - EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); + ProtocolEngineI engine = at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); // encryption is done by the SamlEngine, i.e. by the module we provide in the config // but we need to set the appropriate request issuer - engine.setRequestIssuer(eidasRequest.getEidasRequest().getIssuer()); - + //engine.setRequestIssuer(eidasRequest.getEidasRequest().getIssuer()); - if(null == eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()) { - String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata( - new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()), - engine, - eidasRequest.getEidasRequest()); - eidasRequest.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl); - - } + eIDASRespMsg = engine.generateResponseMessage(eidasRequest.getEidasRequest(), + response, true, eidasRequest.getRemoteAddress()); + +// if(null == eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()) { +// String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata( +// new MOAeIDASMetadataProviderDecorator(eIDASMetadataProvider), +// engine, +// eidasRequest.getEidasRequest()); +// eidasRequest.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl); +// +// } - response = engine.generateEIDASAuthnResponse(eidasRequest.getEidasRequest(), response, eidasRequest.getRemoteAddress(), true); +// response = engine.generateEIDASAuthnResponse(eidasRequest.getEidasRequest(), response, eidasRequest.getRemoteAddress(), true); - token = EIDASUtil.encodeSAMLToken(response.getTokenSaml()); + token = EidasStringUtil.encodeToBase64(eIDASRespMsg.getMessageBytes()); + + } catch(Exception e) { + Logger.error("eIDAS Response encoding error." , e); + throw new MOAIDException("eIDAS.13", new Object[]{e.getMessage()}, e); - } catch(Exception e) { - e.printStackTrace(); } revisionsLogger.logEvent(req, Constants.eIDAS_REVERSIONSLOG_IDP_AUTHREQUEST); @@ -172,10 +259,28 @@ public class eIDASAuthenticationRequest implements IAction { } catch (Exception e) { - Logger.error("Velocity error: " + e.getMessage()); + Logger.error("Velocity error: " + e.getMessage()); + throw new MOAIDException("eIDAS.13", new Object[]{e.getMessage()}, e); + } - - return null; + + SLOInformationInterface ssoContainer = null; + try { + ssoContainer = new SLOInformationImpl( + req.getAuthURL(), + eidasRequest.getEidasRequest().getIssuer(), + null, + subjectNameID, + eidasRequest.getEidasRequest().getNameIdFormat(), + EIDASProtocol.NAME); + + } catch (Exception e) { + Logger.error("Can not generate container with SSO information!", e); + + } + + return ssoContainer; + } @Override @@ -189,4 +294,20 @@ public class eIDASAuthenticationRequest implements IAction { } + private String generateTransientNameID(String nameID) { + String random = Random.nextLongRandom(); + + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + byte[] hash = md.digest((nameID + random).getBytes("ISO-8859-1")); + return Base64Utils.encode(hash); + + } catch (Exception e) { + Logger.error("Can not generate transient personal identifier!", e); + return null; + + } + + } + } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/resources/moaid_eidas_auth.beans.xml b/id/server/modules/moa-id-module-eIDAS/src/main/resources/moaid_eidas_auth.beans.xml index 5d79d082a..20395f210 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/resources/moaid_eidas_auth.beans.xml +++ b/id/server/modules/moa-id-module-eIDAS/src/main/resources/moaid_eidas_auth.beans.xml @@ -14,6 +14,9 @@ <bean id="EIDASProtocol" class="at.gv.egovernment.moa.id.protocols.eidas.EIDASProtocol"/> + + <bean id="eIDASMetadataProvider" + class="at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider"/> <!-- Authentication Process Tasks --> <bean id="GenerateAuthnRequestTask" diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/resources/own-saml-eidasnode-config.xml b/id/server/modules/moa-id-module-eIDAS/src/main/resources/own-saml-eidasnode-config.xml new file mode 100644 index 000000000..856ebd96a --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/resources/own-saml-eidasnode-config.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<XMLTooling xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.opensaml.org/xmltooling-config ../../src/schema/xmltooling-config.xsd" + xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" + xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" + xmlns:stork="urn:eu:stork:names:tc:STORK:1.0:assertion" + xmlns:storkp="urn:eu:stork:names:tc:STORK:1.0:protocol" + xmlns:eidas="http://eidas.europa.eu/saml-extensions" + xmlns="http://www.opensaml.org/xmltooling-config"> + +<!-- SAML 2.0 Protocol Object providers --> + <ValidatorSuites> + <!-- SAML 2.0 Schema Validation Rules --> + + <ValidatorSuite id="moaEidasResponseValidatorSuiteId"> + + <Validator qualifiedName="saml2p:Response" + className="eu.eidas.auth.engine.core.validator.eidas.EidasResponseOneAssertionValidator"/> + + <Validator qualifiedName="saml2p:Response" + className="eu.eidas.auth.engine.core.validator.eidas.EidasResponseValidator"/> + + <Validator qualifiedName="saml2:Assertion" + className="eu.eidas.auth.engine.core.validator.eidas.EidasAssertionValidator"/> + + + <Validator qualifiedName="saml2:Conditions" + className="at.gv.egovernment.moa.id.auth.modules.eidas.engine.validation.MoaEidasConditionsValidator"/> + + <Validator qualifiedName="saml2:AuthnStatement" + className="eu.eidas.auth.engine.core.validator.eidas.EidasAuthnStatementValidator"/> + + <Validator qualifiedName="saml2:Attribute" + className="eu.eidas.auth.engine.core.validator.eidas.EidasAttributeValidator"/> + + </ValidatorSuite> + + + </ValidatorSuites> + + +</XMLTooling>
\ No newline at end of file diff --git a/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandateServiceMetadataProvider.java b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandateServiceMetadataProvider.java index c9485104b..36cd2c7e7 100644 --- a/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandateServiceMetadataProvider.java +++ b/id/server/modules/moa-id-module-elga_mandate_service/src/main/java/at/gv/egovernment/moa/id/auth/modules/elgamandates/utils/ELGAMandateServiceMetadataProvider.java @@ -36,6 +36,7 @@ import org.opensaml.xml.XMLObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import at.gv.egovernment.moa.id.auth.IDestroyableObject; import at.gv.egovernment.moa.id.auth.modules.elgamandates.ELGAMandatesAuthConstants; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.SimpleMOAMetadataProvider; @@ -51,7 +52,8 @@ import at.gv.egovernment.moa.util.MiscUtil; */ @Service("ELGAMandate_MetadataProvider") -public class ELGAMandateServiceMetadataProvider extends SimpleMOAMetadataProvider { +public class ELGAMandateServiceMetadataProvider extends SimpleMOAMetadataProvider + implements IDestroyableObject { @Autowired AuthConfiguration authConfig; @@ -69,6 +71,13 @@ public class ELGAMandateServiceMetadataProvider extends SimpleMOAMetadataProvide } + public void destroy() { + if (metadataProvider != null) + metadataProvider.destroy(); + + } + + /* (non-Javadoc) * @see org.opensaml.saml2.metadata.provider.MetadataProvider#requireValidMetadata() @@ -220,4 +229,16 @@ public class ELGAMandateServiceMetadataProvider extends SimpleMOAMetadataProvide metadataProvider.setRequireValidMetadata(true); } } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.auth.IDestroyableObject#fullyDestroy() + */ + @Override + public void fullyDestroy() { + if (metadataProvider != null) { + metadataProvider.destroy(); + + } + + } } diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SignatureUtil.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SignatureUtil.java index 9f20ee956..cd7b8312d 100644 --- a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SignatureUtil.java +++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/json/OAuth20SignatureUtil.java @@ -54,7 +54,7 @@ public final class OAuth20SignatureUtil { } else if (key instanceof ECPrivateKey) { Logger.debug("OAuth - going to uses SHA256withECDSA signature"); return OAuthSignatureAlgorithm.ECDSA256; - } else if (key instanceof iaik.security.ecc.ecdsa.ECPrivateKey) { + } else if (key instanceof iaik.security.ec.common.ECPrivateKey) { Logger.debug("OAuth - going to uses SHA256withECDSA signature with iaik"); return OAuthSignatureAlgorithm.ECDSA256_IAKIK; } else { @@ -69,7 +69,7 @@ public final class OAuth20SignatureUtil { } else if (key instanceof ECPublicKey) { Logger.debug("OAuth - going to uses SHA256withECDSA signature"); return OAuthSignatureAlgorithm.ECDSA256; - } else if (key instanceof iaik.security.ecc.ecdsa.ECPublicKey) { + } else if (key instanceof iaik.security.ec.common.ECPublicKey) { Logger.debug("OAuth - going to uses SHA256withECDSA signature with iaik"); return OAuthSignatureAlgorithm.ECDSA256_IAKIK; } else { diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java index 803ae388f..b9bed7a22 100644 --- a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java +++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthAction.java @@ -93,7 +93,7 @@ class OAuth20AuthAction implements IAction { // store data in oath session - transactionStorage.put(code, o); + transactionStorage.put(code, o, -1); Logger.debug("Saved OAuth20SessionObject in session with id: " + code); diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java index 98fcdc8dc..258b77b98 100644 --- a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java +++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20AuthRequest.java @@ -28,6 +28,7 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -209,7 +210,7 @@ public class OAuth20AuthRequest extends OAuth20BaseRequest { * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes() */ @Override - public Collection<String> getRequestedAttributes() { + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider) { Map<String, String> reqAttr = new HashMap<String, String>(); for (String el : PVP2XProtocol.DEFAULTREQUESTEDATTRFORINTERFEDERATION) reqAttr.put(el, ""); diff --git a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java index f35de9c58..50638ebf8 100644 --- a/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java +++ b/id/server/modules/moa-id-module-openID/src/main/java/at/gv/egovernment/moa/id/protocols/oauth20/protocol/OAuth20TokenRequest.java @@ -26,6 +26,7 @@ import java.util.Collection; import javax.servlet.http.HttpServletRequest; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -168,7 +169,7 @@ class OAuth20TokenRequest extends OAuth20BaseRequest { * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes() */ @Override - public Collection<String> getRequestedAttributes() { + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider) { return null; } } diff --git a/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/CertTest.java b/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/CertTest.java index 6cf1e8280..35bbac6e7 100644 --- a/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/CertTest.java +++ b/id/server/modules/moa-id-module-openID/src/test/java/test/at/gv/egovernment/moa/id/auth/oauth/CertTest.java @@ -22,15 +22,10 @@ *******************************************************************************/ package test.at.gv.egovernment.moa.id.auth.oauth; -import iaik.security.ecc.provider.ECCProvider; - import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.X509Certificate; -import net.oauth.jsontoken.crypto.Signer; -import net.oauth.jsontoken.crypto.Verifier; - import org.opensaml.xml.security.x509.BasicX509Credential; import org.testng.Assert; import org.testng.annotations.Test; @@ -39,6 +34,9 @@ import at.gv.egovernment.moa.id.protocols.oauth20.json.OAuth20SHA256Signer; import at.gv.egovernment.moa.id.protocols.oauth20.json.OAuth20SHA256Verifier; import at.gv.egovernment.moa.util.KeyStoreUtils; +import net.oauth.jsontoken.crypto.Signer; +import net.oauth.jsontoken.crypto.Verifier; + public class CertTest { /** KeyStore Path */ @@ -122,7 +120,7 @@ public class CertTest { @Test public void testECDSA() throws Exception { - ECCProvider.addAsProvider(); + //ECCProvider.addAsProvider(); // Security.addProvider(new ECCProvider()); BasicX509Credential credential = this.getCredentials(this.ecdsaKeyStorePath); diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferOnlineApplication.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferOnlineApplication.java index af180ff10..3affa17b3 100644 --- a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferOnlineApplication.java +++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/data/SSOTransferOnlineApplication.java @@ -265,7 +265,7 @@ public class SSOTransferOnlineApplication implements IOAAuthParameters { * @see at.gv.egovernment.moa.id.config.auth.IOAAuthParameters#getQaaLevel() */ @Override - public Integer getQaaLevel() { + public String getQaaLevel() { // TODO Auto-generated method stub return null; } diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferServlet.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferServlet.java index b18425839..70b2ebbe9 100644 --- a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferServlet.java +++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferServlet.java @@ -535,7 +535,7 @@ public class SSOTransferServlet{ container.setDhParams(dhKeyIDP); //store container - transactionStorage.put(token, container); + transactionStorage.put(token, container,(int)transmisionTimeOut); //build QR code String containerURL = authURL diff --git a/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/CreateAuthnRequestTask.java b/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/CreateAuthnRequestTask.java index d581e7e75..f5896bc25 100644 --- a/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/CreateAuthnRequestTask.java +++ b/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/CreateAuthnRequestTask.java @@ -62,7 +62,7 @@ public class CreateAuthnRequestTask extends AbstractAuthServletTask { @Autowired PVPAuthnRequestBuilder authnReqBuilder; @Autowired FederatedAuthCredentialProvider credential; - + @Autowired(required=true) MOAMetadataProvider metadataProvider; /* (non-Javadoc) * @see at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) @@ -95,7 +95,7 @@ public class CreateAuthnRequestTask extends AbstractAuthServletTask { } //load IDP SAML2 entitydescriptor - EntityDescriptor idpEntity = MOAMetadataProvider.getInstance(). + EntityDescriptor idpEntity = metadataProvider. getEntityDescriptor(idpEntityID); if (idpEntity == null) { Logger.warn("Requested IDP " + idpEntityID diff --git a/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/ReceiveAuthnResponseTask.java b/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/ReceiveAuthnResponseTask.java index 1c3134b77..f739940c8 100644 --- a/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/ReceiveAuthnResponseTask.java +++ b/id/server/modules/moa-id-modules-federated_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/federatedauth/tasks/ReceiveAuthnResponseTask.java @@ -90,7 +90,7 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { @Autowired private SSOManager ssoManager; @Autowired private AttributQueryBuilder attributQueryBuilder; @Autowired private AuthenticationDataBuilder authDataBuilder; - + @Autowired(required=true) MOAMetadataProvider metadataProvider; /* (non-Javadoc) @@ -125,7 +125,7 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { //decode PVP response object msg = (InboundMessage) decoder.decode( - request, response, MOAMetadataProvider.getInstance(), true, + request, response, metadataProvider, true, comperator); if (MiscUtil.isEmpty(msg.getEntityID())) { @@ -135,7 +135,7 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { //validate response signature if(!msg.isVerified()) { - samlVerificationEngine.verify(msg, TrustEngineFactory.getSignatureKnownKeysTrustEngine(MOAMetadataProvider.getInstance())); + samlVerificationEngine.verify(msg, TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); msg.setVerified(true); } @@ -247,7 +247,7 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { try { Logger.debug("Service Provider is no federated IDP --> start Attribute validation or requesting ... "); - Collection<String> requestedAttr = pendingReq.getRequestedAttributes(); + Collection<String> requestedAttr = pendingReq.getRequestedAttributes(metadataProvider); //check if SAML2 Assertion contains a minimal set of attributes if (!extractor.containsAllRequiredAttributes()) { @@ -267,7 +267,7 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { //check if all attributes are include if (!extractor.containsAllRequiredAttributes( - pendingReq.getRequestedAttributes())) { + pendingReq.getRequestedAttributes(metadataProvider))) { Logger.warn("PVP Response from federated IDP contains not all requested attributes."); throw new AssertionValidationExeption("sp.pvp2.06", new Object[]{FederatedAuthConstants.MODULE_NAME_FOR_LOGGING}); diff --git a/id/server/modules/moa-id-modules-saml1/pom.xml b/id/server/modules/moa-id-modules-saml1/pom.xml index 323edee8d..0463bf8d9 100644 --- a/id/server/modules/moa-id-modules-saml1/pom.xml +++ b/id/server/modules/moa-id-modules-saml1/pom.xml @@ -26,6 +26,13 @@ </dependency> <dependency> + <groupId>MOA.id.server</groupId> + <artifactId>moa-id-commons</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> + + <dependency> <groupId>MOA.id.server</groupId> <artifactId>moa-id-lib</artifactId> </dependency> diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java index c421bf8cc..d3ebffdfd 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java @@ -22,16 +22,12 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.protocols.saml1; -import java.util.List; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants; -import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.servlet.RedirectServlet; import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; @@ -43,7 +39,6 @@ import at.gv.egovernment.moa.id.data.SLOInformationInterface; import at.gv.egovernment.moa.id.moduls.IAction; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.URLEncoder; -import eu.eidas.auth.commons.IPersonalAttributeList; @Service("SAML1_GetArtifactAction") public class GetArtifactAction implements IAction { @@ -74,13 +69,16 @@ public class GetArtifactAction implements IAction { try { IOAAuthParameters oaParam = req.getOnlineApplicationConfiguration(); + //TODO: add eIDAS to SAML1 protocol if it is really necessary + // add other stork attributes to MOA assertion if available - IPersonalAttributeList storkAttributes = authData.getGenericData( - AuthenticationSessionStorageConstants.STORK_ATTRIBUTELIST, - IPersonalAttributeList.class); +// IPersonalAttributeList storkAttributes = authData.getGenericData( +// AuthenticationSessionStorageConstants.STORK_ATTRIBUTELIST, +// IPersonalAttributeList.class); + Object storkAttributes = null; if(null != storkAttributes) { - List<ExtendedSAMLAttribute> moaExtendedSAMLAttibutes = saml1server.addAdditionalSTORKAttributes(storkAttributes); - authData.getExtendedSAMLAttributesOA().addAll(moaExtendedSAMLAttibutes); +// List<ExtendedSAMLAttribute> moaExtendedSAMLAttibutes = saml1server.addAdditionalSTORKAttributes(storkAttributes); +// authData.getExtendedSAMLAttributesOA().addAll(moaExtendedSAMLAttibutes); Logger.info("MOA assertion assembled and SAML Artifact generated."); } diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java index 0ec0d95a2..0a760cb5a 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java @@ -25,7 +25,6 @@ package at.gv.egovernment.moa.id.protocols.saml1; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.List; -import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -37,7 +36,6 @@ import javax.xml.namespace.QName; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; -import org.apache.commons.lang3.StringEscapeUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.w3c.dom.Element; @@ -52,7 +50,6 @@ import at.gv.egovernment.moa.id.auth.builder.PersonDataBuilder; import at.gv.egovernment.moa.id.auth.builder.SAMLArtifactBuilder; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute; -import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttributeImpl; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.exception.BuildException; import at.gv.egovernment.moa.id.auth.exception.ParseException; @@ -82,8 +79,6 @@ import at.gv.util.xsd.persondata.IdentificationType.Value; import at.gv.util.xsd.persondata.PersonNameType; import at.gv.util.xsd.persondata.PersonNameType.FamilyName; import at.gv.util.xsd.persondata.PhysicalPersonType; -import eu.eidas.auth.commons.IPersonalAttributeList; -import eu.eidas.auth.commons.PersonalAttribute; //import at.gv.egovernment.moa.id.util.IdentityLinkReSigner; @Service("SAML1AuthenticationServer") @@ -95,7 +90,7 @@ public class SAML1AuthenticationServer extends AuthenticationServer { * time out in milliseconds used by {@link cleanup} for authentication data * store */ - private static final long authDataTimeOut = 2 * 60 * 1000; // default 2 minutes + private static final int authDataTimeOut = 2 * 60 * 1000; // default 2 minutes public Throwable getErrorResponse(String samlArtifact) throws AuthenticationException { @@ -127,41 +122,43 @@ public class SAML1AuthenticationServer extends AuthenticationServer { return error; } - /** - * Transforms additional STORK attributes to MOA Extended attributes - * @param iPersonalAttributeList STORK attribute list - * @return - */ - public List<ExtendedSAMLAttribute> addAdditionalSTORKAttributes(IPersonalAttributeList iPersonalAttributeList) { - List<ExtendedSAMLAttribute> moaExtendedSAMLAttributeList = new Vector<ExtendedSAMLAttribute>(); - - if(null == iPersonalAttributeList) - return moaExtendedSAMLAttributeList; - - Logger.trace("Adding the following attributes to MOA assertion: "); - int count = 0; - - for (PersonalAttribute attribute : iPersonalAttributeList) { - Object attributeValue = attribute.getValue(); - if (null == attributeValue) - attributeValue = attribute.getComplexValue(); - - // escape attributeValue - attributeValue = StringEscapeUtils.escapeXml10(attributeValue.toString()); - // and remove trailing and tailing brackets. Might break something but we never saw an array with more than one entry! - attributeValue = ((String) attributeValue).substring(1, ((String) attributeValue).length() - 1); - - ExtendedSAMLAttribute extendedSAMLAttribute = - new ExtendedSAMLAttributeImpl(attribute.getName(), attributeValue, Constants.STORK_NS_URI, 0); - moaExtendedSAMLAttributeList.add(extendedSAMLAttribute); - count++; - Logger.trace("Additional attribute: " + attribute.getName()); - } - - Logger.debug("Added " + count + " STORK attribute(s) to the MOA assertion."); - - return moaExtendedSAMLAttributeList; - } + + //TODO: add eIDAS to SAML1 protocol if it is really necessary +// /** +// * Transforms additional STORK attributes to MOA Extended attributes +// * @param iPersonalAttributeList STORK attribute list +// * @return +// */ +// public List<ExtendedSAMLAttribute> addAdditionalSTORKAttributes(IPersonalAttributeList iPersonalAttributeList) { +// List<ExtendedSAMLAttribute> moaExtendedSAMLAttributeList = new Vector<ExtendedSAMLAttribute>(); +// +// if(null == iPersonalAttributeList) +// return moaExtendedSAMLAttributeList; +// +// Logger.trace("Adding the following attributes to MOA assertion: "); +// int count = 0; +// +// for (PersonalAttribute attribute : iPersonalAttributeList) { +// Object attributeValue = attribute.getValue(); +// if (null == attributeValue) +// attributeValue = attribute.getComplexValue(); +// +// // escape attributeValue +// attributeValue = StringEscapeUtils.escapeXml10(attributeValue.toString()); +// // and remove trailing and tailing brackets. Might break something but we never saw an array with more than one entry! +// attributeValue = ((String) attributeValue).substring(1, ((String) attributeValue).length() - 1); +// +// ExtendedSAMLAttribute extendedSAMLAttribute = +// new ExtendedSAMLAttributeImpl(attribute.getName(), attributeValue, Constants.STORK_NS_URI, 0); +// moaExtendedSAMLAttributeList.add(extendedSAMLAttribute); +// count++; +// Logger.trace("Additional attribute: " + attribute.getName()); +// } +// +// Logger.debug("Added " + count + " STORK attribute(s) to the MOA assertion."); +// +// return moaExtendedSAMLAttributeList; +// } /** @@ -210,7 +207,7 @@ public class SAML1AuthenticationServer extends AuthenticationServer { protocolRequest.getOAURL(), protocolRequest.getRequestID(), null); - authenticationDataStore.put(samlArtifact, error); + authenticationDataStore.put(samlArtifact, error, authDataTimeOut); return samlArtifact; } @@ -721,7 +718,7 @@ public class SAML1AuthenticationServer extends AuthenticationServer { //synchronized (authenticationDataStore) { Logger.debug("Assertion stored for SAML Artifact: " + samlArtifact); - authenticationDataStore.put(samlArtifact, samlAssertion); + authenticationDataStore.put(samlArtifact, samlAssertion,authDataTimeOut); //} } catch (AuthenticationException ex) { diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java index 42fafc01e..1d3525626 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -81,7 +82,7 @@ public class SAML1RequestImpl extends RequestImpl { * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes() */ @Override - public Collection<String> getRequestedAttributes() { + public Collection<String> getRequestedAttributes(MetadataProvider metadataProvider) { List<String> reqAttr = new ArrayList<String>(); reqAttr.addAll(SAML1Protocol.DEFAULTREQUESTEDATTRFORINTERFEDERATION); diff --git a/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/auth/servlet/MonitoringServlet.java b/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/auth/servlet/MonitoringController.java index 9adf2edc3..b232b9512 100644 --- a/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/auth/servlet/MonitoringServlet.java +++ b/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/auth/servlet/MonitoringController.java @@ -24,7 +24,6 @@ package at.gv.egovernment.moa.id.auth.servlet; import java.io.IOException; import java.io.PrintWriter; -import java.util.Arrays; import java.util.List; import javax.servlet.ServletException; @@ -37,39 +36,51 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; -import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.monitoring.TestManager; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; @Controller -public class MonitoringServlet { +public class MonitoringController { private static final String REQUEST_ATTR_MODULE = "module"; @Autowired private AuthConfiguration authConfig; + @Autowired private TestManager tests; - public MonitoringServlet() { + public MonitoringController() { super(); Logger.debug("Registering servlet " + getClass().getName() + " with mapping '/MonitoringServlet'."); } @RequestMapping(value = "/MonitoringServlet", method = RequestMethod.GET) public void getStatusInformation(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { + throws ServletException, IOException{ - try { - if (authConfig.isMonitoringActive()) { - Logger.debug("Monitoring Servlet received request"); + if (authConfig.isMonitoringActive()) { + Logger.debug("Monitoring Servlet received request"); - TestManager tests = TestManager.getInstance(); - - String modulename = req.getParameter(REQUEST_ATTR_MODULE); - if (MiscUtil.isEmpty(modulename)) { + + + String modulename = req.getParameter(REQUEST_ATTR_MODULE); + if (MiscUtil.isEmpty(modulename)) { + + List<String> error = tests.executeTests(); + if (error != null && error.size() > 0) { + createErrorMessage(req, resp, error); + + } else { + resp.setStatus(HttpServletResponse.SC_OK); + resp.setContentType("text/html;charset=UTF-8"); + resp.getWriter().write(getHtml(authConfig.getMonitoringMessageSuccess())); + Logger.info("Monitoring Servlet finished without errors"); + } - List<String> error = tests.executeTests(); - if (error != null && error.size() > 0) { - createErrorMessage(req, resp, error); + } else { + if (tests.existsModule(modulename)) { + List<String> errors = tests.executeTest(modulename); + if (errors != null && errors.size() > 0) { + createErrorMessage(req, resp, errors); } else { resp.setStatus(HttpServletResponse.SC_OK); @@ -79,38 +90,21 @@ public class MonitoringServlet { } } else { - if (tests.existsModule(modulename)) { - List<String> errors = tests.executeTest(modulename); - if (errors != null && errors.size() > 0) { - createErrorMessage(req, resp, errors); - - } else { - resp.setStatus(HttpServletResponse.SC_OK); - resp.setContentType("text/html;charset=UTF-8"); - resp.getWriter().write(getHtml(authConfig.getMonitoringMessageSuccess())); - Logger.info("Monitoring Servlet finished without errors"); - } - - } else { - Logger.warn("NO Testmodule exists with modulename " + modulename); - resp.setStatus(HttpServletResponse.SC_NOT_FOUND); - resp.setContentType("text/html;charset=UTF-8"); - PrintWriter out; - try { - out = new PrintWriter(resp.getOutputStream()); - out.write("NO Testmodule exists with modulename " + modulename); - out.flush(); - - } catch (IOException e) { - Logger.warn("Internal Monitoring Servlet Error. ", e); - } - } - - } - } - - } catch (ConfigurationException e) { - createErrorMessage(req, resp, Arrays.asList(e.getMessage())); + Logger.warn("NO Testmodule exists with modulename " + modulename); + resp.setStatus(HttpServletResponse.SC_NOT_FOUND); + resp.setContentType("text/html;charset=UTF-8"); + PrintWriter out; + try { + out = new PrintWriter(resp.getOutputStream()); + out.write("NO Testmodule exists with modulename " + modulename); + out.flush(); + + } catch (IOException e) { + Logger.warn("Internal Monitoring Servlet Error. ", e); + } + } + + } } } diff --git a/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/monitoring/DatabaseTestModule.java b/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/monitoring/DatabaseTestModule.java index 5e4183146..8ae1850ce 100644 --- a/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/monitoring/DatabaseTestModule.java +++ b/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/monitoring/DatabaseTestModule.java @@ -40,6 +40,14 @@ import at.gv.egovernment.moa.util.MiscUtil; public class DatabaseTestModule implements TestModuleInterface{ + private MOASessionDBUtils dbUtils; + private StatisticLogDBUtils statLogUtils; + + public DatabaseTestModule(MOASessionDBUtils dbUtils, StatisticLogDBUtils statLogUtils){ + this.statLogUtils = statLogUtils; + this.dbUtils = dbUtils; + } + public List<String> performTests() throws Exception { Logger.trace("Start MOA-ID Database Test."); @@ -70,9 +78,10 @@ public class DatabaseTestModule implements TestModuleInterface{ Date expioredate = new Date(new Date().getTime() - 120); + try { List<AssertionStore> results; - Session session = MOASessionDBUtils.getCurrentSession(); + Session session = dbUtils.getCurrentSession(); synchronized (session) { session.beginTransaction(); @@ -105,7 +114,7 @@ public class DatabaseTestModule implements TestModuleInterface{ Date expioredate = new Date(new Date().getTime() - 120); try { - Session session = StatisticLogDBUtils.getCurrentSession(); + Session session = statLogUtils.getCurrentSession(); List<StatisticLog> results; diff --git a/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/monitoring/MonitoringSpringResourceProvider.java b/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/monitoring/MonitoringSpringResourceProvider.java new file mode 100644 index 000000000..0f7dfc7fe --- /dev/null +++ b/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/monitoring/MonitoringSpringResourceProvider.java @@ -0,0 +1,29 @@ +package at.gv.egovernment.moa.id.monitoring; + +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import at.gv.egiz.components.spring.api.SpringResourceProvider; + +public class MonitoringSpringResourceProvider implements SpringResourceProvider{ + + @Override + public String getName() { + // TODO Auto-generated method stub + return "MOA-ID Monitoring Module"; + } + + @Override + public String[] getPackagesToScan() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource[] getResourcesToLoad() { + ClassPathResource monitoringResource = new ClassPathResource("/moaid_monitoring.beans.xml", MonitoringSpringResourceProvider.class); + + return new Resource[] {monitoringResource}; + } + +} diff --git a/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/monitoring/TestManager.java b/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/monitoring/TestManager.java index b25eed520..4224fae59 100644 --- a/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/monitoring/TestManager.java +++ b/id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/monitoring/TestManager.java @@ -27,49 +27,29 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; + import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; -import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils; +import at.gv.egovernment.moa.id.commons.db.StatisticLogDBUtils; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.FileUtils; -public class TestManager { - - private static TestManager instance; +public class TestManager{ + @Autowired private MOASessionDBUtils moaSessionDBUtils; + @Autowired(required=false) private StatisticLogDBUtils statisticLogDBUtils = null; + @Autowired private AuthConfiguration authConfig; private Map<String, TestModuleInterface> tests = new HashMap<String, TestModuleInterface>(); - public static TestManager getInstance() throws ConfigurationException { - if (instance == null) - instance = new TestManager(); - - return instance; - } - - private TestManager() throws ConfigurationException { - - AuthConfiguration config = AuthConfigurationProviderFactory.getInstance(); - - //add Database test - DatabaseTestModule test1 = new DatabaseTestModule(); - tests.put(test1.getName(), test1); - - //add IdentityLink verification test - IdentityLinkTestModule test2 = new IdentityLinkTestModule(); - String idlurl = FileUtils.makeAbsoluteURL(config.getMonitoringTestIdentityLinkURL(), config.getRootConfigFileDir()); - try { - test2.initializeTest(0, idlurl); - tests.put(test2.getName(), test2);; - - } catch (Exception e) { - Logger.warn("MOA-ID IdentityLink Test can not performed without IdentityLink. Insert IdentityLink file to MOA-ID configuration", e); - } + public TestManager(){ + } public List<String> executeTests() { Logger.debug("Start MOA-ID-Auth testing"); - List<String> errors; for (TestModuleInterface test : tests.values()) { @@ -109,4 +89,24 @@ public class TestManager { public boolean existsModule(String modulename) { return tests.containsKey(modulename); } + + public void init() throws ConfigurationException{ + Logger.debug("Start initializing MOA-ID-Auth TestManager"); + + //add Database test + DatabaseTestModule test1 = new DatabaseTestModule(this.moaSessionDBUtils, this.statisticLogDBUtils); + tests.put(test1.getName(), test1); + + //add IdentityLink verification test + IdentityLinkTestModule test2 = new IdentityLinkTestModule(); + String idlurl = FileUtils.makeAbsoluteURL(authConfig.getMonitoringTestIdentityLinkURL(), authConfig.getRootConfigFileDir()); + try { + test2.initializeTest(0, idlurl); + tests.put(test2.getName(), test2);; + + } catch (Exception e) { + Logger.warn("MOA-ID IdentityLink Test can not performed without IdentityLink. Insert IdentityLink file to MOA-ID configuration", e); + } + } + } diff --git a/id/server/modules/module-monitoring/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider b/id/server/modules/module-monitoring/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider new file mode 100644 index 000000000..b696bcdd7 --- /dev/null +++ b/id/server/modules/module-monitoring/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider @@ -0,0 +1 @@ +at.gv.egovernment.moa.id.monitoring.MonitoringSpringResourceProvider
\ No newline at end of file diff --git a/id/server/modules/module-monitoring/src/main/resources/moaid_monitoring.beans.xml b/id/server/modules/module-monitoring/src/main/resources/moaid_monitoring.beans.xml new file mode 100644 index 000000000..6c195e7d7 --- /dev/null +++ b/id/server/modules/module-monitoring/src/main/resources/moaid_monitoring.beans.xml @@ -0,0 +1,16 @@ +<?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"> + + <bean id="testManager" + class="at.gv.egovernment.moa.id.monitoring.TestManager" + init-method="init"/> +</beans>
\ No newline at end of file diff --git a/id/server/pom.xml b/id/server/pom.xml index 56d317cf5..1824bf272 100644 --- a/id/server/pom.xml +++ b/id/server/pom.xml @@ -104,7 +104,7 @@ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
- <version>4.11</version>
+ <version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
|