aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules/moa-id-module-eIDAS
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/modules/moa-id-module-eIDAS')
-rw-r--r--id/server/modules/moa-id-module-eIDAS/pom.xml22
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java84
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOASWSigner.java56
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLEngineConfigurationImpl.java34
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLInstanceConfigurationImpl.java57
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java83
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java (renamed from id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDAsExtensionProcessor.java)35
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java90
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataProviderDecorator.java44
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/validation/MoaEidasConditionsValidator.java83
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASAuthnRequestProcessingException.java (renamed from id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAuthnRequestProcessingException.java)10
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASAuthnRequestValidationException.java (renamed from id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAuthnRequestValidationException.java)4
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineException.java2
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASException.java (renamed from id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASException.java)6
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASResponseBuildException.java (renamed from id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASResponseBuildException.java)6
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASResponseNotSuccessException.java (renamed from id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASResponseNotSuccessException.java)6
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAttributeException.java2
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CreateIdentityLinkTask.java66
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java189
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java70
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAOrderedAttributeIterator.java66
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAPersonalAttributeList.java343
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAProtocolEngineFactory.java99
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java621
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java107
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SimpleEidasAttributeGenerator.java68
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java25
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java230
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java52
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java229
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/resources/moaid_eidas_auth.beans.xml3
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/resources/own-saml-eidasnode-config.xml42
32 files changed, 2028 insertions, 806 deletions
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/MOAeIDAsExtensionProcessor.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java
index 5837d7dbf..c24c5efca 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/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java
@@ -22,27 +22,36 @@
*/
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;
+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 MOAeIDAsExtensionProcessor extends EidasExtensionProcessor implements ExtensionProcessorI {
+public class MOAEidasProtocolProcesser extends EidasProtocolProcessor {
+ private static final String OWN_EIDAS_RESPONSE_VALIDATOR_SUITE_ID = "moaEidasResponseValidatorSuiteId";
+
+ private final MetadataFetcherI metadataFetcher;
+ private final MetadataSignerI metadataSigner;
+
/**
- * Add only eIDAS attributes which are supported by Austrian eIDAS node
- *
+ * @param metadataFetcher
+ * @param metadataSigner
*/
+ public MOAEidasProtocolProcesser(MetadataFetcherI metadataFetcher, MetadataSignerI metadataSigner) {
+ super(metadataFetcher, metadataSigner);
+
+ this.metadataFetcher = metadataFetcher;
+ this.metadataSigner = metadataSigner;
+
+ }
+
@Override
- public Set<String> getSupportedAttributes(){
- Set<String> supportedAttributes=new HashSet<String>( Constants.METADATA_POSSIBLE_ATTRIBUTES.keySet());
-
- return supportedAttributes;
+ 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..0cb6228a7 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();
- } catch (FilterException | MetadataProviderException e) {
+ //provider.getMetadataFilter().doFilter(provider.getMetadata());
+
+ } catch (MetadataProviderException e) {
Logger.info("eIDAS MetadataProvider: " + provider.getMetadataURI()
+ " is not valid any more. Reason:" + e.getMessage());
if (Logger.isDebugEnabled())
@@ -182,11 +206,11 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi
try {
MOAHttpProtocolSocketFactory protoSocketFactory = new MOAHttpProtocolSocketFactory(
Constants.SSLSOCKETFACTORYNAME,
- authConfig.getCertstoreDirectory(),
authConfig.getTrustedCACertificates(),
null,
AuthConfiguration.DEFAULT_X509_CHAININGMODE,
- authConfig.isTrustmanagerrevoationchecking());
+ authConfig.isTrustmanagerrevoationchecking(),
+ authConfig.getRevocationMethodOrder());
httpClient.setCustomSSLTrustStore(metadataURL, protoSocketFactory);
@@ -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
@@ -282,14 +306,17 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi
} else {
//load new Metadata Provider
ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider;
- HTTPMetadataProvider newMetadataProvider = createNewHTTPMetaDataProvider(metadataURL);
- chainProvider.addMetadataProvider(newMetadataProvider);
+ HTTPMetadataProvider newMetadataProvider = createNewHTTPMetaDataProvider(metadataURL);
- emitChangeEvent();
- Logger.info("eIDAS metadata for "
- + metadataURL + " is added.");
- return true;
-
+ if (newMetadataProvider != null) {
+ chainProvider.addMetadataProvider(newMetadataProvider);
+
+ emitChangeEvent();
+ Logger.info("eIDAS metadata for "
+ + metadataURL + " is added.");
+ return true;
+
+ }
}
} else
@@ -405,5 +432,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..cf3a13e32 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,18 +28,20 @@ import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.joda.time.DateTime;
import org.springframework.stereotype.Component;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants;
-import at.gv.egovernment.moa.id.auth.data.IdentityLink;
import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
import at.gv.egovernment.moa.id.auth.modules.eidas.Constants;
import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASAttributeException;
+import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils;
import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser;
+import at.gv.egovernment.moa.id.commons.api.data.IIdentityLink;
import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException;
import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
import at.gv.egovernment.moa.id.process.api.ExecutionContext;
@@ -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,11 +69,11 @@ 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;
+ IIdentityLink identityLink = null;
//connect SZR-Gateway
//TODO: implement SZR-Gateway communication!!!!
@@ -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();
@@ -144,7 +162,7 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask {
moasession.setBkuURL("Not applicable (eIDASAuthentication)");
//store MOA-session to database
- authenticatedSessionStorage.storeSession(moasession);
+ requestStoreage.storePendingRequest(pendingReq);
} catch (eIDASAttributeException e) {
throw new TaskExecutionException(pendingReq, "Minimum required eIDAS attributeset not found.", e);
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..c4b2bfeae 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,
@@ -88,17 +111,20 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask {
moasession.setGenericDataToSession(PVPConstants.EID_ISSUING_NATION_NAME, samlResp.getCountry());
//store MOA-session to database
- authenticatedSessionStorage.storeSession(moasession);
+ requestStoreage.storePendingRequest(pendingReq);
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