summaryrefslogtreecommitdiff
path: root/eaaf_modules
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_modules')
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/pom.xml6
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SamlAssertionValidationExeption.java28
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SamlMessageValidationException.java18
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/InboundMessage.java16
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java7
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/Saml2Utils.java5
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/SamlVerificationEngine.java355
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/resources/messages/pvp_messages.properties4
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java2
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/Pvp2SProfileCoreSpringResourceProviderTest.java56
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/QaaLevelVerifierTest.java147
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/SamlVerificationEngineTest.java720
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java157
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java159
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/dummy/DummyMetadataProvider.java80
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/ChainingMetadataTest.java166
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataBuilderTest.java24
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/Asserion_enc_no_key.xml81
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/AuthRequest_without_sig_missing_id.xml11
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/Response_without_sig_1.xml2
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/Response_without_sig_classpath_entityid.xml52
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/eIDAS_connector_authn.xml54
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_junit_keystore.xml31
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_junit_keystore_classpath_entityId.xml204
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_valid_with_entityCategory_egov.xml2
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_map_config.beans.xml6
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_spring_config.beans.xml7
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_pvp.beans.xml5
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/pom.xml6
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java30
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java14
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthenticationActionTest.java226
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthnResponseBuilderTest.java54
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/MetadataActionTest.java67
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/Pvp2SProfileIdpSpringResourceProviderTest.java56
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyLoALevelMapper.java25
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpConfiguration.java43
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpMetadataConfigFactory.java16
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummySubjectNameGenerator.java18
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/pvp_metadata_junit_keystore.xml31
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml5
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_pvp.beans.xml28
-rw-r--r--eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java27
43 files changed, 2838 insertions, 213 deletions
diff --git a/eaaf_modules/eaaf_module_pvp2_core/pom.xml b/eaaf_modules/eaaf_module_pvp2_core/pom.xml
index 318fa500..a81ad889 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/pom.xml
+++ b/eaaf_modules/eaaf_module_pvp2_core/pom.xml
@@ -66,6 +66,12 @@
</dependency>
<dependency>
<groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf_core_utils</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
<artifactId>eaaf-core</artifactId>
<scope>test</scope>
<type>test-jar</type>
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SamlAssertionValidationExeption.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SamlAssertionValidationExeption.java
new file mode 100644
index 00000000..9ba7ccb2
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SamlAssertionValidationExeption.java
@@ -0,0 +1,28 @@
+package at.gv.egiz.eaaf.modules.pvp2.exception;
+
+public class SamlAssertionValidationExeption extends SamlMessageValidationException {
+
+ private static final long serialVersionUID = 2054578783736917817L;
+
+ /**
+ * In case of a SAML2-Assertion validation error.
+ *
+ * @param messageId errorId
+ * @param parameters Message parameters
+ */
+ public SamlAssertionValidationExeption(String messageId, Object[] parameters) {
+ super(messageId, parameters);
+ }
+
+ /**
+ * In case of a SAML2-Assertion validation error.
+ *
+ * @param messageId errorId
+ * @param parameters Message parameters
+ * @param wrapped Exception that was thrown
+ */
+ public SamlAssertionValidationExeption(String messageId, Object[] parameters, Throwable wrapped) {
+ super(messageId, parameters, wrapped);
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SamlMessageValidationException.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SamlMessageValidationException.java
index 774d0927..56d8c4a5 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SamlMessageValidationException.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/exception/SamlMessageValidationException.java
@@ -4,6 +4,24 @@ public class SamlMessageValidationException extends Pvp2Exception {
private static final long serialVersionUID = 2545822499416501014L;
+ /**
+ * In case of a SAML2-message validation error.
+ *
+ * @param messageId errorId
+ * @param parameters Message parameters
+ */
+ public SamlMessageValidationException(String messageId, Object[] parameters) {
+ super(messageId, parameters);
+
+ }
+
+ /**
+ * In case of a SAML2-message validation error.
+ *
+ * @param messageId errorId
+ * @param parameters Message parameters
+ * @param wrapped Exception that was thrown
+ */
public SamlMessageValidationException(String messageId, Object[] parameters, Throwable wrapped) {
super(messageId, parameters, wrapped);
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/InboundMessage.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/InboundMessage.java
index 0ffa3789..f77243c2 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/InboundMessage.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/message/InboundMessage.java
@@ -22,20 +22,20 @@ package at.gv.egiz.eaaf.modules.pvp2.impl.message;
import java.io.IOException;
import java.io.Serializable;
+import javax.annotation.Nonnull;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
-import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
-import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface;
-import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
-import at.gv.egiz.eaaf.modules.pvp2.exception.NoMetadataInformationException;
-
import org.opensaml.saml.saml2.metadata.EntityDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
+import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
+import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.NoMetadataInformationException;
import net.shibboleth.utilities.java.support.resolver.ResolverException;
public class InboundMessage implements InboundMessageInterface, Serializable {
@@ -57,13 +57,9 @@ public class InboundMessage implements InboundMessageInterface, Serializable {
* @return EntityDescriptor from metadata
* @throws NoMetadataInformationException In case of an error
*/
- public EntityDescriptor getEntityMetadata(final IPvp2MetadataProvider metadataProvider)
+ public EntityDescriptor getEntityMetadata(@Nonnull final IPvp2MetadataProvider metadataProvider)
throws NoMetadataInformationException {
try {
- if (metadataProvider == null) {
- throw new NullPointerException("No PVP MetadataProvider found.");
- }
-
return metadataProvider.getEntityDescriptor(this.entityID);
} catch (final ResolverException e) {
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java
index b9d0161f..902f84c7 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java
@@ -447,13 +447,6 @@ public abstract class AbstractChainingMetadataProvider implements IGarbageCollec
destroyMetadataResolver(resolver);
internalResolvers.remove(resolver);
- /*
- * OpenSAML ChainingMetadataProvider can not remove a MetadataProvider
- * (UnsupportedOperationException) The ChainingMetadataProvider use internal a
- * unmodifiableList to hold all registrated MetadataProviders.
- */
- // chainProvider.removeMetadataProvider(provider);
-
}
}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/Saml2Utils.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/Saml2Utils.java
index a3154b0d..c476846b 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/Saml2Utils.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/Saml2Utils.java
@@ -134,10 +134,7 @@ public class Saml2Utils {
@Nonnull EaafX509Credential signingCredential, boolean injectCertificate) throws SamlSigningException {
try {
- final String usedSigAlg = getKeyOperationAlgorithmFromCredential(signingCredential,
- PvpConstants.DEFAULT_SIGNING_METHODE_RSA,
- PvpConstants.DEFAULT_SIGNING_METHODE_EC);
-
+ final String usedSigAlg = signingCredential.getSignatureAlgorithmForSigning();
final Signature signature = createSignature(signingCredential, usedSigAlg, injectCertificate);
toSign.setSignature(signature);
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/SamlVerificationEngine.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/SamlVerificationEngine.java
index 2e26de7f..e0a3ab8e 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/SamlVerificationEngine.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/verification/SamlVerificationEngine.java
@@ -19,6 +19,9 @@
package at.gv.egiz.eaaf.modules.pvp2.impl.verification;
+import java.util.ArrayList;
+import java.util.List;
+
import javax.xml.namespace.QName;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
@@ -26,27 +29,45 @@ import javax.xml.validation.Validator;
import at.gv.egiz.eaaf.core.exceptions.EaafProtocolException;
import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException;
+import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlAssertionValidationExeption;
import at.gv.egiz.eaaf.modules.pvp2.exception.SchemaValidationException;
import at.gv.egiz.eaaf.modules.pvp2.impl.message.InboundMessage;
import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileRequest;
import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileResponse;
import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
import org.opensaml.core.criterion.EntityIdCriterion;
import org.opensaml.saml.common.xml.SAMLConstants;
import org.opensaml.saml.common.xml.SAMLSchemaBuilder;
import org.opensaml.saml.common.xml.SAMLSchemaBuilder.SAML1Version;
import org.opensaml.saml.criterion.EntityRoleCriterion;
import org.opensaml.saml.criterion.ProtocolCriterion;
+import org.opensaml.saml.saml2.core.Assertion;
+import org.opensaml.saml.saml2.core.Audience;
+import org.opensaml.saml.saml2.core.AudienceRestriction;
+import org.opensaml.saml.saml2.core.Conditions;
+import org.opensaml.saml.saml2.core.EncryptedAssertion;
import org.opensaml.saml.saml2.core.RequestAbstractType;
+import org.opensaml.saml.saml2.core.Response;
+import org.opensaml.saml.saml2.core.StatusCode;
import org.opensaml.saml.saml2.core.StatusResponseType;
+import org.opensaml.saml.saml2.encryption.Decrypter;
+import org.opensaml.saml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver;
import org.opensaml.saml.saml2.metadata.IDPSSODescriptor;
import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
import org.opensaml.saml.security.impl.SAMLSignatureProfileValidator;
import org.opensaml.security.credential.UsageType;
import org.opensaml.security.criteria.UsageCriterion;
+import org.opensaml.xmlsec.encryption.support.ChainingEncryptedKeyResolver;
+import org.opensaml.xmlsec.encryption.support.DecryptionException;
+import org.opensaml.xmlsec.encryption.support.EncryptedKeyResolver;
+import org.opensaml.xmlsec.encryption.support.InlineEncryptedKeyResolver;
+import org.opensaml.xmlsec.encryption.support.SimpleRetrievalMethodEncryptedKeyResolver;
+import org.opensaml.xmlsec.keyinfo.impl.StaticKeyInfoCredentialResolver;
import org.opensaml.xmlsec.signature.support.SignatureException;
import org.opensaml.xmlsec.signature.support.SignatureTrustEngine;
import org.springframework.beans.factory.annotation.Autowired;
@@ -54,18 +75,40 @@ import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import lombok.extern.slf4j.Slf4j;
+import net.shibboleth.utilities.java.support.net.BasicURLComparator;
+import net.shibboleth.utilities.java.support.net.URIException;
import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
@Slf4j
public class SamlVerificationEngine {
private static SAMLSchemaBuilder schemaBuilder = new SAMLSchemaBuilder(SAML1Version.SAML_11);
+ private static final String ERROR_03 = "internal.pvp.03";
+ private static final String ERROR_10 = "internal.pvp.10";
+ private static final String ERROR_14 = "internal.pvp.14";
+ private static final String ERROR_15 = "internal.pvp.15";
+ private static final String ERROR_16 = "internal.pvp.16";
+ private static final String ERROR_17 = "internal.pvp.17";
+
+ private static final Object SIG_VAL_ERROR_MSG = "Signature verification return false";
+
+ /**
+ * 5 allow 3 minutes time jitter in before validation.
+ */
+ private static final int TIME_JITTER = 3;
+
+
+
+
+
@Autowired(required = true)
IPvp2MetadataProvider metadataProvider;
/**
* Verify signature of a signed SAML2 object.
*
+ *<p>This method only perform signature verification</p>
+ *
* @param msg SAML2 message
* @param sigTrustEngine TrustEngine
* @throws org.opensaml.xml.security.SecurityException In case of invalid
@@ -85,7 +128,7 @@ public class SamlVerificationEngine {
} else {
log.warn("SAML2 message type: {} not supported", msg.getClass().getName());
- throw new EaafProtocolException("9999", null);
+ throw new EaafProtocolException("internal.pvp.99", null);
}
@@ -94,13 +137,14 @@ public class SamlVerificationEngine {
throw e;
}
- log.debug(
- "PVP2X message validation FAILED. Relead metadata for entityID: " + msg.getEntityID());
+ log.debug("PVP2X message validation FAILED. Relead metadata for entityID: {}",
+ msg.getEntityID());
if (metadataProvider == null || !(metadataProvider instanceof IRefreshableMetadataProvider)
|| !((IRefreshableMetadataProvider) metadataProvider)
.refreshMetadataProvider(msg.getEntityID())) {
throw e;
+
} else {
log.trace("PVP2X metadata reload finished. Check validate message again.");
@@ -108,30 +152,261 @@ public class SamlVerificationEngine {
&& ((PvpSProfileRequest) msg).getSamlRequest() instanceof RequestAbstractType) {
verifyRequest((RequestAbstractType) ((PvpSProfileRequest) msg).getSamlRequest(),
sigTrustEngine);
+
} else {
verifyIdpResponse(((PvpSProfileResponse) msg).getResponse(), sigTrustEngine);
+
}
}
log.trace("Second PVP2X message validation finished");
+
}
}
+ /**
+ * Verify the signature of a signed SAML2 object from ServiceProvider.
+ *
+ * @param samlObj signed Response from ServiceProvider
+ * @param sigTrustEngine TrustEngie for verification
+ * @throws InvalidProtocolRequestException In case of a verification error
+ */
public void verifySloResponse(final StatusResponseType samlObj,
final SignatureTrustEngine sigTrustEngine) throws InvalidProtocolRequestException {
verifyResponse(samlObj, sigTrustEngine, SPSSODescriptor.DEFAULT_ELEMENT_NAME);
}
+ /**
+ * Verify the signature of a signed SAML2 object from IDP.
+ *
+ * <p>This method only perform signature verification</p>
+ *
+ * @param samlObj signed SAML2 message from IDP
+ * @param sigTrustEngine TrustEngie for verification
+ * @throws InvalidProtocolRequestException In case of a verification error
+ */
public void verifyIdpResponse(final StatusResponseType samlObj,
final SignatureTrustEngine sigTrustEngine) throws InvalidProtocolRequestException {
verifyResponse(samlObj, sigTrustEngine, IDPSSODescriptor.DEFAULT_ELEMENT_NAME);
}
+ /**
+ * Validate a PVP response and all included assertions.
+ *
+ *<p>
+ * If the SAML2 assertions are encrypted than they will be decrypted afterwards
+ * </p>
+ *
+ *<p>This method <b>DOES NOT</b> verify the <i>Destination</i> attribute in SAML2 Response</p>
+ *
+ * @param samlResp SAML2 Response object
+ * @param assertionDecryption Assertion decryption-credentials to decrypt SAML2
+ * assertions
+ * @param spEntityID EntityId of the SAML2 client
+ * @param loggerName Name for logging purposes
+ * @throws SamlAssertionValidationExeption In case of a validation error
+ */
+ public void validateAssertion(Response samlResp,
+ EaafX509Credential assertionDecryption, String spEntityID, String loggerName)
+ throws SamlAssertionValidationExeption {
+ validateAssertion(samlResp, assertionDecryption, spEntityID, loggerName, true);
+
+ }
+
+ /**
+ * Validate each SAML2 assertions in a SAML2 response. <br>
+ * <p>
+ * If the SAML2 assertions are encrypted than they will be decrypted afterwards
+ * </p>
+ *
+ *<p>This method <b>DOES NOT</b> verify the <i>Destination</i> attribute in SAML2 Response</p>
+ *
+ * @param samlResp SAML2 Response object
+ * @param assertionDecryption Assertion decryption-credentials to decrypt SAML2
+ * assertions
+ * @param spEntityID EntityId of the SAML2 client
+ * @param loggerName Name for logging purposes
+ * @param validateDateTime <code>true</code> if <i>getIssueInstant</i>
+ * attribute should be validated, otherwise false
+ * @throws SamlAssertionValidationExeption In case of a validation error
+ */
+ public void validateAssertion(Response samlResp, EaafX509Credential assertionDecryption,
+ String spEntityID, String loggerName, boolean validateDateTime)
+ throws SamlAssertionValidationExeption {
+ try {
+ // pre-validate the SAML2 response
+ assertionPreValidation(samlResp, loggerName, validateDateTime);
+
+ // get Assertion from response and decrypt them if the are encrypted
+ final List<Assertion> saml2assertions = getOrDecryptAndGetAssertions(samlResp, assertionDecryption);
+
+ // validate each assertion
+ final List<Assertion> validatedassertions = new ArrayList<>();
+ for (final Assertion saml2assertion : saml2assertions) {
+ if (internalAssertionValidation(saml2assertion, spEntityID, validateDateTime)) {
+ log.debug("Add valid Assertion:" + saml2assertion.getID());
+ validatedassertions.add(saml2assertion);
+
+ } else {
+ log.warn("Remove non-valid Assertion:" + saml2assertion.getID());
+ }
+
+ }
+
+ if (validatedassertions.isEmpty()) {
+ log.info("No valid PVP 2.1 assertion received.");
+ throw new SamlAssertionValidationExeption(ERROR_15, new Object[] { loggerName });
+
+ }
+
+ samlResp.getAssertions().clear();
+ samlResp.getEncryptedAssertions().clear();
+ samlResp.getAssertions().addAll(validatedassertions);
+
+ } catch (final DecryptionException e) {
+ log.warn("Assertion decrypt FAILED.", e);
+ throw new SamlAssertionValidationExeption(ERROR_16,
+ new Object[] { e.getMessage() }, e);
+
+// } catch (final ConfigurationException e) {
+// throw new AssertionValidationExeption("pvp.12",
+// new Object[]{loggerName, e.getMessage()}, e);
+ }
+ }
+
+ private boolean internalAssertionValidation(Assertion saml2assertion, String spEntityId,
+ boolean validateDateTime) {
+ boolean isAssertionValid = true;
+ try {
+ // schema validation
+ performSchemaValidation(saml2assertion.getDOM());
+
+ // validate DateTime conditions
+ final Conditions conditions = saml2assertion.getConditions();
+ if (conditions != null) {
+ final DateTime notbefore = conditions.getNotBefore().minusMinutes(5);
+ final DateTime notafter = conditions.getNotOnOrAfter();
+ if (validateDateTime
+ && (notbefore.isAfterNow() || notafter.isBeforeNow())) {
+ isAssertionValid = false;
+ log.info("Assertion with ID:{} is out of Date. [ Current:{} NotBefore:{} NotAfter:{} ]",
+ saml2assertion.getID(), new DateTime(), notbefore, notafter);
+
+ }
+
+ // validate audienceRestrictions are valid for this SP
+ final List<AudienceRestriction> audienceRest = conditions.getAudienceRestrictions();
+ if (audienceRest == null || audienceRest.size() == 0) {
+ log.info("Assertion with ID:{} has not 'AudienceRestriction' element",
+ saml2assertion.getID());
+ isAssertionValid = false;
+
+ } else {
+ for (final AudienceRestriction el : audienceRest) {
+ for (final Audience audience : el.getAudiences()) {
+ if (!urlCompare(spEntityId, audience.getAudienceURI())) {
+ log.info("Assertion with ID:{} 'AudienceRestriction' is not valid.",
+ saml2assertion.getID());
+ isAssertionValid = false;
+
+ }
+ }
+ }
+ }
+
+ } else {
+ log.info("Assertion with ID:{} contains not 'Conditions' element",
+ saml2assertion.getID());
+ isAssertionValid = false;
+
+ }
+
+ } catch (final SchemaValidationException e) {
+ isAssertionValid = false;
+ log.info("Assertion with ID:{} FAILED Schema validation. Msg: {}",
+ saml2assertion.getID(), e.getMessage());
+
+ } catch (final URIException e) {
+ isAssertionValid = false;
+ log.info("Assertion with ID:{} FAILED AudienceRestriction validation. Msg:",
+ saml2assertion.getID(), e.getMessage());
+
+ }
+
+ return isAssertionValid;
+
+ }
+
+ private List<Assertion> getOrDecryptAndGetAssertions(Response samlResp,
+ EaafX509Credential assertionDecryption) throws DecryptionException {
+ final List<Assertion> saml2assertions = new ArrayList<>();
+
+ // check encrypted Assertions
+ final List<EncryptedAssertion> encryAssertionList = samlResp.getEncryptedAssertions();
+ if (encryAssertionList != null && encryAssertionList.size() > 0) {
+ // decrypt assertions
+ log.debug("Found encryped assertion. Start decryption ...");
+ final List<EncryptedKeyResolver> listOfKeyResolvers = new ArrayList<>();
+ listOfKeyResolvers.add(new InlineEncryptedKeyResolver());
+ listOfKeyResolvers.add(new EncryptedElementTypeEncryptedKeyResolver());
+ listOfKeyResolvers.add(new SimpleRetrievalMethodEncryptedKeyResolver());
+
+ final Decrypter samlDecrypter = new Decrypter(null,
+ new StaticKeyInfoCredentialResolver(assertionDecryption),
+ new ChainingEncryptedKeyResolver(listOfKeyResolvers));
+
+ for (final EncryptedAssertion encAssertion : encryAssertionList) {
+ saml2assertions.add(samlDecrypter.decrypt(encAssertion));
+
+ }
+ log.debug("Assertion decryption finished. ");
+
+ }
+
+ saml2assertions.addAll(samlResp.getAssertions());
+
+ return saml2assertions;
+
+ }
+
+ private void performSchemaValidation(final Element source) throws SchemaValidationException {
+
+ String err = null;
+ try {
+ final Schema test = schemaBuilder.getSAMLSchema();
+ final Validator val = test.newValidator();
+ val.validate(new DOMSource(source));
+ log.debug("Schema validation check done OK");
+ return;
+
+ } catch (final SAXException e) {
+ err = e.getMessage();
+ if (log.isDebugEnabled() || log.isTraceEnabled()) {
+ log.warn("Schema validation FAILED with exception:", e);
+ } else {
+ log.warn("Schema validation FAILED with message: " + e.getMessage());
+ }
+
+ } catch (final Exception e) {
+ err = e.getMessage();
+ if (log.isDebugEnabled() || log.isTraceEnabled()) {
+ log.warn("Schema validation FAILED with exception:", e);
+ } else {
+ log.warn("Schema validation FAILED with message: " + e.getMessage());
+ }
+
+ }
+
+ throw new SchemaValidationException(ERROR_03, new Object[] { err });
+
+ }
+
private void verifyResponse(final StatusResponseType samlObj,
final SignatureTrustEngine sigTrustEngine, final QName defaultElementName)
throws InvalidProtocolRequestException {
+
final SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
try {
profileValidator.validate(samlObj.getSignature());
@@ -139,10 +414,10 @@ public class SamlVerificationEngine {
} catch (final SignatureException e) {
log.warn("Signature is not conform to SAML signature profile", e);
- throw new InvalidProtocolRequestException("pvp2.21", new Object[] {});
+ throw new InvalidProtocolRequestException(ERROR_10, new Object[] {e.getMessage() }, e);
} catch (final SchemaValidationException e) {
- throw new InvalidProtocolRequestException("pvp2.22", new Object[] { e.getMessage() });
+ throw new InvalidProtocolRequestException(ERROR_03, new Object[] { e.getMessage() }, e);
}
@@ -154,11 +429,14 @@ public class SamlVerificationEngine {
try {
if (!sigTrustEngine.validate(samlObj.getSignature(), criteriaSet)) {
- throw new InvalidProtocolRequestException("pvp2.21", new Object[] {});
+ throw new InvalidProtocolRequestException(ERROR_10, new Object[] {SIG_VAL_ERROR_MSG});
+
}
+
} catch (final org.opensaml.security.SecurityException e) {
log.warn("PVP2x message signature validation FAILED.", e);
- throw new InvalidProtocolRequestException("pvp2.21", new Object[] {});
+ throw new InvalidProtocolRequestException(ERROR_10, new Object[] {e.getMessage()}, e);
+
}
}
@@ -171,10 +449,10 @@ public class SamlVerificationEngine {
} catch (final SignatureException e) {
log.warn("Signature is not conform to SAML signature profile", e);
- throw new InvalidProtocolRequestException("pvp2.21", new Object[] {});
+ throw new InvalidProtocolRequestException(ERROR_10, new Object[] {e.getMessage()}, e);
} catch (final SchemaValidationException e) {
- throw new InvalidProtocolRequestException("pvp2.22", new Object[] { e.getMessage() });
+ throw new InvalidProtocolRequestException(ERROR_03, new Object[] { e.getMessage() }, e);
}
@@ -186,44 +464,53 @@ public class SamlVerificationEngine {
try {
if (!sigTrustEngine.validate(samlObj.getSignature(), criteriaSet)) {
- throw new InvalidProtocolRequestException("pvp2.21", new Object[] {});
+ throw new InvalidProtocolRequestException(ERROR_10, new Object[] {SIG_VAL_ERROR_MSG});
+
}
} catch (final org.opensaml.security.SecurityException e) {
log.warn("PVP2x message signature validation FAILED.", e);
- throw new InvalidProtocolRequestException("pvp2.21", new Object[] {});
+ throw new InvalidProtocolRequestException(ERROR_10, new Object[] {e.getMessage()}, e);
+
}
+
}
- protected void performSchemaValidation(final Element source) throws SchemaValidationException {
+ private void assertionPreValidation(Response samlResp, String loggerName, boolean validateDateTime)
+ throws SamlAssertionValidationExeption {
+ if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS)) {
+ // validate response issueInstant
+ final DateTime issueInstant = samlResp.getIssueInstant();
+ if (issueInstant == null) {
+ log.warn("PVP response does not include a 'IssueInstant' attribute");
+ throw new SamlAssertionValidationExeption(ERROR_14,
+ new Object[] { loggerName, "'IssueInstant' attribute is not included" });
- String err = null;
- try {
- final Schema test = schemaBuilder.getSAMLSchema();
- final Validator val = test.newValidator();
- val.validate(new DOMSource(source));
- log.debug("Schema validation check done OK");
- return;
-
- } catch (final SAXException e) {
- err = e.getMessage();
- if (log.isDebugEnabled() || log.isTraceEnabled()) {
- log.warn("Schema validation FAILED with exception:", e);
- } else {
- log.warn("Schema validation FAILED with message: " + e.getMessage());
}
+ if (validateDateTime && issueInstant.minusMinutes(TIME_JITTER).isAfterNow()) {
+ log.warn("PVP response: IssueInstant DateTime is not valid anymore.");
+ throw new SamlAssertionValidationExeption(ERROR_14,
+ new Object[] { loggerName, "'IssueInstant' Time is not valid any more" });
- } catch (final Exception e) {
- err = e.getMessage();
- if (log.isDebugEnabled() || log.isTraceEnabled()) {
- log.warn("Schema validation FAILED with exception:", e);
- } else {
- log.warn("Schema validation FAILED with message: " + e.getMessage());
}
- }
+ } else {
+ log.info("PVP 2.x assertion includes an error. Receive errorcode "
+ + samlResp.getStatus().getStatusCode().getValue());
+ throw new SamlAssertionValidationExeption(ERROR_17,
+ new Object[] { loggerName,
+ samlResp.getIssuer().getValue(),
+ samlResp.getStatus().getStatusCode().getValue(),
+ samlResp.getStatus().getStatusMessage() != null
+ ? samlResp.getStatus().getStatusMessage().getMessage()
+ : " no status message" });
- throw new SchemaValidationException("pvp2.22", new Object[] { err });
+ }
+ }
+ private static boolean urlCompare(String url1, String url2) throws URIException {
+ final BasicURLComparator comparator = new BasicURLComparator();
+ comparator.setCaseInsensitive(false);
+ return comparator.compare(url1, url2);
}
}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/resources/messages/pvp_messages.properties b/eaaf_modules/eaaf_module_pvp2_core/src/main/resources/messages/pvp_messages.properties
index 8a91c68c..824f17d4 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/resources/messages/pvp_messages.properties
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/resources/messages/pvp_messages.properties
@@ -12,6 +12,10 @@ internal.pvp.10=Signature verification of SAML2 message FAILED. Reason: {0}
internal.pvp.11=General SAML2 message validation error. Reason: {0}
internal.pvp.12=SAML2 metadata: {0} is NOT signed
internal.pvp.13=SAML2 metadata generation failed. Reason: {0}
+internal.pvp.14=SAML2 assertion validator: {0} found an error: Reason {1}
+internal.pvp.15=SAML2 assertion validator: {0} find NO valid assertion in SAML2 response.
+internal.pvp.16=Decryption of SAML2 assertion FAILED with reason: {0}
+internal.pvp.17=SAML2 assertion validator:{0} find invalid PVP Response from Issuer:{1}. StatusCodes:{2} Msg:{3}
pvp2.21=Signature validation of SAML2 Authn. request failed. Reason: {0}
pvp2.22=Validation of SAML2 Authn. request failed. Reason: {0}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java
index 3ba4629e..22ee389f 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/CredentialProviderTest.java
@@ -28,7 +28,7 @@ import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
- "/spring/test_eaaf_core_spring_config.beans.xml",
+ "/spring/test_eaaf_core_map_config.beans.xml",
"/spring/SpringTest-context_lazy.xml"
})
@TestPropertySource(locations = {"/config/config_1.props"})
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/Pvp2SProfileCoreSpringResourceProviderTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/Pvp2SProfileCoreSpringResourceProviderTest.java
new file mode 100644
index 00000000..67c59dec
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/Pvp2SProfileCoreSpringResourceProviderTest.java
@@ -0,0 +1,56 @@
+package at.gv.egiz.eaaf.modules.pvp2.test;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.springframework.core.io.Resource;
+
+import at.gv.egiz.eaaf.core.test.TestConstants;
+import at.gv.egiz.eaaf.modules.pvp2.Pvp2SProfileCoreSpringResourceProvider;
+
+
+
+@RunWith(BlockJUnit4ClassRunner.class)
+public class Pvp2SProfileCoreSpringResourceProviderTest {
+
+ @Test
+ public void testSpringConfig() {
+ final Pvp2SProfileCoreSpringResourceProvider test =
+ new Pvp2SProfileCoreSpringResourceProvider();
+ for (final Resource el : test.getResourcesToLoad()) {
+ try {
+ IOUtils.toByteArray(el.getInputStream());
+
+ } catch (final IOException e) {
+ Assert.fail("Ressouce: " + el.getFilename() + " not found");
+ }
+
+ }
+
+ Assert.assertNotNull("no Name", test.getName());
+ Assert.assertNull("Find package definitions", test.getPackagesToScan());
+
+ }
+
+ @Test
+ public void testSpILoaderConfig() {
+ final InputStream el = this.getClass().getResourceAsStream(TestConstants.TEST_SPI_LOADER_PATH);
+ try {
+ final String spiFile = IOUtils.toString(el, "UTF-8");
+
+ Assert.assertEquals("Wrong classpath in SPI file",
+ Pvp2SProfileCoreSpringResourceProvider.class.getName(), spiFile);
+
+
+ } catch (final IOException e) {
+ Assert.fail("Ressouce: " + TestConstants.TEST_SPI_LOADER_PATH + " not found");
+
+ }
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/QaaLevelVerifierTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/QaaLevelVerifierTest.java
new file mode 100644
index 00000000..44cdf111
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/QaaLevelVerifierTest.java
@@ -0,0 +1,147 @@
+package at.gv.egiz.eaaf.modules.pvp2.test;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.modules.pvp2.exception.QaaNotAllowedException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.QaaLevelVerifier;
+
+@RunWith(BlockJUnit4ClassRunner.class)
+public class QaaLevelVerifierTest {
+
+ QaaLevelVerifier verifyer = new QaaLevelVerifier();
+
+ @Test
+ public void matchingModeUnknown() {
+ String matchingMode = "notExist";
+ List<String> requiredLoAs = Arrays.asList(EaafConstants.EIDAS_LOA_SUBSTANTIAL);
+
+ try {
+ QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_LOW, requiredLoAs, matchingMode);
+ Assert.fail("LoA should not be allowed");
+
+ } catch (QaaNotAllowedException e) {
+
+ }
+
+ try {
+ QaaLevelVerifier.verifyQaaLevel("not_exist", requiredLoAs, matchingMode);
+ Assert.fail("LoA should not be allowed");
+
+ } catch (QaaNotAllowedException e) {
+
+ }
+
+ }
+
+ @Test
+ public void matchingMinimumRequiredLow() throws QaaNotAllowedException {
+ String matchingMode = EaafConstants.EIDAS_LOA_MATCHING_MINIMUM;
+ List<String> requiredLoAs = Arrays.asList(EaafConstants.EIDAS_LOA_LOW);
+
+ QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_LOW, requiredLoAs, matchingMode);
+ QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_SUBSTANTIAL, requiredLoAs, matchingMode);
+ QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_HIGH, requiredLoAs, matchingMode);
+
+ try {
+ QaaLevelVerifier.verifyQaaLevel("not_exist", requiredLoAs, matchingMode);
+ Assert.fail("LoA should not be allowed");
+
+ } catch (QaaNotAllowedException e) {
+
+ }
+
+ }
+
+ @Test
+ public void matchingMinimumRequiredSubstantial() throws QaaNotAllowedException {
+ String matchingMode = EaafConstants.EIDAS_LOA_MATCHING_MINIMUM;
+ List<String> requiredLoAs = Arrays.asList(EaafConstants.EIDAS_LOA_SUBSTANTIAL);
+
+ try {
+ QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_LOW, requiredLoAs, matchingMode);
+ Assert.fail("LoA should not be allowed");
+
+ } catch (QaaNotAllowedException e) {
+
+ }
+
+ QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_SUBSTANTIAL, requiredLoAs, matchingMode);
+ QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_HIGH, requiredLoAs, matchingMode);
+
+ try {
+ QaaLevelVerifier.verifyQaaLevel("not_exist", requiredLoAs, matchingMode);
+ Assert.fail("LoA should not be allowed");
+
+ } catch (QaaNotAllowedException e) {
+
+ }
+
+ }
+
+ @Test
+ public void matchingMinimumRequiredHigh() throws QaaNotAllowedException {
+ String matchingMode = EaafConstants.EIDAS_LOA_MATCHING_MINIMUM;
+ List<String> requiredLoAs = Arrays.asList(EaafConstants.EIDAS_LOA_HIGH);
+
+ try {
+ QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_LOW, requiredLoAs, matchingMode);
+ Assert.fail("LoA should not be allowed");
+
+ } catch (QaaNotAllowedException e) {
+
+ }
+
+ try {
+ QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_SUBSTANTIAL, requiredLoAs, matchingMode);
+ Assert.fail("LoA should not be allowed");
+
+ } catch (QaaNotAllowedException e) {
+
+ }
+
+ QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_HIGH, requiredLoAs, matchingMode);
+
+ try {
+ QaaLevelVerifier.verifyQaaLevel("not_exist", requiredLoAs, matchingMode);
+ Assert.fail("LoA should not be allowed");
+
+ } catch (QaaNotAllowedException e) {
+
+ }
+
+ }
+
+ @Test
+ public void matchingExact1() throws QaaNotAllowedException {
+ String matchingMode = EaafConstants.EIDAS_LOA_MATCHING_EXACT;
+ List<String> requiredLoAs = Arrays.asList(EaafConstants.EIDAS_LOA_SUBSTANTIAL, EaafConstants.EIDAS_LOA_LOW);
+
+ try {
+ QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_HIGH, requiredLoAs, matchingMode);
+ Assert.fail("LoA should not be allowed");
+
+ } catch (QaaNotAllowedException e) {
+
+ }
+
+ QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_LOW, requiredLoAs, matchingMode);
+ QaaLevelVerifier.verifyQaaLevel(EaafConstants.EIDAS_LOA_SUBSTANTIAL, requiredLoAs, matchingMode);
+
+ try {
+ QaaLevelVerifier.verifyQaaLevel("not_exist", requiredLoAs, matchingMode);
+ Assert.fail("LoA should not be allowed");
+
+ } catch (QaaNotAllowedException e) {
+
+ }
+
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/SamlVerificationEngineTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/SamlVerificationEngineTest.java
new file mode 100644
index 00000000..66e87537
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/SamlVerificationEngineTest.java
@@ -0,0 +1,720 @@
+package at.gv.egiz.eaaf.modules.pvp2.test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EaafProtocolException;
+import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.modules.pvp2.PvpConstants;
+import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2InternalErrorException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlAssertionValidationExeption;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileRequest;
+import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileResponse;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyMetadataProvider;
+
+import org.joda.time.DateTime;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.core.xml.io.UnmarshallingException;
+import org.opensaml.core.xml.util.XMLObjectSupport;
+import org.opensaml.saml.common.xml.SAMLConstants;
+import org.opensaml.saml.saml2.core.Assertion;
+import org.opensaml.saml.saml2.core.AuthnRequest;
+import org.opensaml.saml.saml2.core.EncryptedAssertion;
+import org.opensaml.saml.saml2.core.Issuer;
+import org.opensaml.saml.saml2.core.Response;
+import org.opensaml.saml.saml2.core.StatusCode;
+import org.opensaml.saml.saml2.encryption.Encrypter;
+import org.opensaml.saml.saml2.encryption.Encrypter.KeyPlacement;
+import org.opensaml.security.x509.X509Credential;
+import org.opensaml.xmlsec.SecurityConfigurationSupport;
+import org.opensaml.xmlsec.encryption.support.DataEncryptionParameters;
+import org.opensaml.xmlsec.encryption.support.EncryptionException;
+import org.opensaml.xmlsec.encryption.support.KeyEncryptionParameters;
+import org.opensaml.xmlsec.keyinfo.KeyInfoGeneratorFactory;
+import org.opensaml.xmlsec.signature.support.SignatureConstants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.util.Assert;
+import org.w3c.dom.Element;
+
+import net.shibboleth.utilities.java.support.xml.XMLParserException;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration({ "/spring/test_eaaf_pvp.beans.xml",
+ "/spring/test_eaaf_core_spring_config.beans.xml" })
+@TestPropertySource(locations = { "/config/config_1.props" })
+public class SamlVerificationEngineTest {
+
+ @Autowired
+ private PvpMetadataResolverFactory metadataResolverFactory;
+ @Autowired
+ private SamlVerificationEngine verifyEngine;
+ @Autowired
+ private DummyCredentialProvider credentialProvider;
+
+ @Autowired DummyMetadataProvider metadataProvider;
+ @Autowired IConfiguration authConfig;
+
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void classInitializer() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ }
+
+ @Test
+ public void validateSamlRequestSuccess() throws SecurityException, Exception {
+
+ final String authnReqPath = "/data/AuthRequest_without_sig_1.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml";
+ final String spEntityId = metadataPath;
+
+ final Pair<AuthnRequest, IPvp2MetadataProvider> inputMsg =
+ initializeAuthnRequest(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final PvpSProfileRequest msg = new PvpSProfileRequest(
+ inputMsg.getFirst(),
+ SAMLConstants.SAML2_POST_BINDING_URI);
+ msg.setEntityID(spEntityId);
+
+ verifyEngine.verify(msg,
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+
+ }
+
+ @Test
+ public void validateSamlRequestWrongSignature() throws SecurityException, Exception {
+
+ final String authnReqPath = "/data/AuthRequest_without_sig_1.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = metadataPath;
+
+ final Pair<AuthnRequest, IPvp2MetadataProvider> inputMsg =
+ initializeAuthnRequest(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ metadataProvider.addMetadataResolverIntoChain(inputMsg.getSecond());
+
+ final PvpSProfileRequest msg = new PvpSProfileRequest(
+ inputMsg.getFirst(),
+ SAMLConstants.SAML2_POST_BINDING_URI);
+ msg.setEntityID(spEntityId);
+
+ try {
+ verifyEngine.verify(msg,
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+ org.junit.Assert.fail("Wrong signature not detected");
+
+ } catch (final Exception e) {
+ Assert.isInstanceOf(InvalidProtocolRequestException.class, e, "Wrong exceptionType");
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.10", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void validateSamlInvalidRequest() throws SecurityException, Exception {
+
+ final String authnReqPath = "/data/AuthRequest_without_sig_missing_id.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = metadataPath;
+
+ final Pair<AuthnRequest, IPvp2MetadataProvider> inputMsg =
+ initializeAuthnRequest(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ metadataProvider.addMetadataResolverIntoChain(inputMsg.getSecond());
+
+ final PvpSProfileRequest msg = new PvpSProfileRequest(
+ inputMsg.getFirst(),
+ SAMLConstants.SAML2_POST_BINDING_URI);
+ msg.setEntityID(spEntityId);
+
+ try {
+ verifyEngine.verify(msg,
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+ org.junit.Assert.fail("invalid request not detected");
+
+ } catch (final Exception e) {
+ Assert.isInstanceOf(InvalidProtocolRequestException.class, e, "Wrong exceptionType");
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.03", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void validateSamlRequestWrongSignatureAlg() throws SecurityException, Exception {
+
+ final String authnReqPath = "/data/AuthRequest_without_sig_1.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = metadataPath;
+
+ metadataProvider.runGarbageCollector();
+
+ final EaafX509Credential cred = credentialProvider.getMetaDataSigningCredential();
+ cred.setSignatureAlgorithmForSigning(SignatureConstants.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5);
+ final Pair<AuthnRequest, IPvp2MetadataProvider> inputMsg =
+ initializeAuthnRequest(spEntityId, metadataPath, authnReqPath,
+ cred);
+
+ final PvpSProfileRequest msg = new PvpSProfileRequest(
+ inputMsg.getFirst(),
+ SAMLConstants.SAML2_POST_BINDING_URI);
+ msg.setEntityID(spEntityId);
+
+ try {
+ verifyEngine.verify(msg,
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+ org.junit.Assert.fail("Wrong SigAlg not detected");
+
+ } catch (final Exception e) {
+ Assert.isInstanceOf(EaafProtocolException.class, e, "Wrong exceptionType");
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.99", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void verifyResponseSuccessTest() throws Pvp2InternalErrorException, SecurityException, Exception {
+ metadataProvider.runGarbageCollector();
+
+ final String authnReqPath = "/data/Response_without_sig_1.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml";
+ final String spEntityId = metadataPath;
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final PvpSProfileResponse msg = new PvpSProfileResponse(
+ inputMsg.getFirst());
+ msg.setEntityID(spEntityId);
+
+ verifyEngine.verify(msg,
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+
+ }
+
+ @Test
+ public void verifyResponseSuccessSecondTest()
+ throws Pvp2InternalErrorException, SecurityException, Exception {
+
+ final String authnReqPath = "/data/Response_without_sig_1.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml";
+ final String spEntityId = metadataPath;
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ verifyEngine.verifyIdpResponse(inputMsg.getFirst(),
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+
+ }
+
+ @Test
+ public void verifySpResponse()
+ throws Pvp2InternalErrorException, SecurityException, Exception {
+
+ final String authnReqPath = "/data/Response_without_sig_1.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml";
+ final String spEntityId = metadataPath;
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ verifyEngine.verifySloResponse(inputMsg.getFirst(),
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+
+ }
+
+ @Test
+ public void verifyResponseWithoutId() throws Pvp2InternalErrorException, SecurityException, Exception {
+
+ final String authnReqPath = "/data/Response_with_sig_1.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml";
+ final String spEntityId = metadataPath;
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final PvpSProfileResponse msg = new PvpSProfileResponse(
+ inputMsg.getFirst());
+ msg.setEntityID(spEntityId);
+
+ try {
+ verifyEngine.verify(msg,
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+ org.junit.Assert.fail("Wrong XML schema not detected");
+
+ } catch (final Exception e) {
+ Assert.isInstanceOf(InvalidProtocolRequestException.class, e, "Wrong exceptionType");
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.03", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void verifyResponseWrongTrust() throws Pvp2InternalErrorException, SecurityException, Exception {
+
+ final String authnReqPath = "/data/Response_without_sig_1.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = metadataPath;
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final PvpSProfileResponse msg = new PvpSProfileResponse(
+ inputMsg.getFirst());
+ msg.setEntityID(spEntityId);
+
+ try {
+ verifyEngine.verify(msg,
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+ org.junit.Assert.fail("No TrustedCert not detected");
+
+ } catch (final Exception e) {
+ Assert.isInstanceOf(InvalidProtocolRequestException.class, e, "Wrong exceptionType");
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.10", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void verifyAssertionSucessNotEncrypted() throws SamlSigningException, Pvp2MetadataException,
+ CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption {
+ final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/";
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ verifyEngine.validateAssertion(inputMsg.getFirst(), credentialProvider.getMetaDataSigningCredential(),
+ spEntityId, "jUnit Test", false);
+
+
+ }
+
+ @Test
+ public void verifyAssertionWrongAudiency() throws SamlSigningException, Pvp2MetadataException,
+ CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption {
+ final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = "https://demo.egiz.gv.at/";
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+ try {
+ verifyEngine.validateAssertion(inputMsg.getFirst(), credentialProvider.getMetaDataSigningCredential(),
+ spEntityId, "jUnit Test", false);
+ org.junit.Assert.fail("Wrong Audiency not detected");
+
+ } catch (final SamlAssertionValidationExeption e) {
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void verifyAssertionWrongStatusCode() throws SamlSigningException, Pvp2MetadataException,
+ CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption {
+ final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/";
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final Response response = inputMsg.getFirst();
+ response.getStatus().getStatusCode().setValue(StatusCode.RESPONDER);
+
+ try {
+ verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(),
+ spEntityId, "jUnit Test", false);
+ org.junit.Assert.fail("Wrong StatusCode not detected");
+
+ } catch (final SamlAssertionValidationExeption e) {
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.17", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void verifyAssertionWrongIssueInstant() throws SamlSigningException, Pvp2MetadataException,
+ CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption {
+ final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/";
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final Response response = inputMsg.getFirst();
+ response.setIssueInstant(DateTime.now().plusMinutes(10));
+
+ try {
+ verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(),
+ spEntityId, "jUnit Test", true);
+ org.junit.Assert.fail("Wrong date not detected");
+
+ } catch (final SamlAssertionValidationExeption e) {
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.14", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void verifyAssertionNoContitions() throws SamlSigningException, Pvp2MetadataException,
+ CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption {
+ final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/";
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final Response response = inputMsg.getFirst();
+ response.getAssertions().get(0).setConditions(null);
+
+ try {
+ verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(),
+ spEntityId, "jUnit Test", true);
+ org.junit.Assert.fail("Wrong date not detected");
+
+ } catch (final SamlAssertionValidationExeption e) {
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void verifyAssertionWrongContitions() throws SamlSigningException, Pvp2MetadataException,
+ CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption {
+ final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/";
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final Response response = inputMsg.getFirst();
+
+ try {
+ verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(),
+ spEntityId, "jUnit Test", true);
+ org.junit.Assert.fail("Wrong date not detected");
+
+ } catch (final SamlAssertionValidationExeption e) {
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void verifyAssertionWrongContitionsAudienceRestrictions() throws SamlSigningException, Pvp2MetadataException,
+ CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption {
+ final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/";
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final Response response = inputMsg.getFirst();
+ response.getAssertions().get(0).getConditions().setNotBefore(DateTime.now());
+ response.getAssertions().get(0).getConditions().setNotOnOrAfter(DateTime.now().plusMinutes(15));
+ response.getAssertions().get(0).getConditions().getAudienceRestrictions().clear();
+
+ try {
+ verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(),
+ spEntityId, "jUnit Test", true);
+ org.junit.Assert.fail("Wrong date not detected");
+
+ } catch (final SamlAssertionValidationExeption e) {
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void verifyAssertionWrongContitionsNotBefore() throws SamlSigningException, Pvp2MetadataException,
+ CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption {
+ final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/";
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final Response response = inputMsg.getFirst();
+ response.getAssertions().get(0).getConditions().setNotBefore(DateTime.now().plusMinutes(10));
+ response.getAssertions().get(0).getConditions().setNotOnOrAfter(DateTime.now().plusMinutes(15));
+
+ try {
+ verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(),
+ spEntityId, "jUnit Test", true);
+ org.junit.Assert.fail("Wrong date not detected");
+
+ } catch (final SamlAssertionValidationExeption e) {
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void verifyAssertionWrongContitionsNotOnOrAfter() throws SamlSigningException, Pvp2MetadataException,
+ CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption {
+ final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/";
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final Response response = inputMsg.getFirst();
+ response.getAssertions().get(0).getConditions().setNotBefore(DateTime.now());
+ response.getAssertions().get(0).getConditions().setNotOnOrAfter(DateTime.now().minusMinutes(5));
+
+ try {
+ verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(),
+ spEntityId, "jUnit Test", true);
+ org.junit.Assert.fail("Wrong date not detected");
+
+ } catch (final SamlAssertionValidationExeption e) {
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void verifyAssertionValidContitions() throws SamlSigningException, Pvp2MetadataException,
+ CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption {
+ final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/";
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final Response response = inputMsg.getFirst();
+ response.getAssertions().get(0).getConditions().setNotBefore(DateTime.now());
+ response.getAssertions().get(0).getConditions().setNotOnOrAfter(DateTime.now().plusMinutes(5));
+
+
+ verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(),
+ spEntityId, "jUnit Test", true);
+
+ }
+
+ @Test
+ public void verifyEncAssertionWrongKey() throws SamlSigningException, Pvp2MetadataException,
+ CredentialsNotAvailableException, XMLParserException, UnmarshallingException, SamlAssertionValidationExeption {
+ final String authnReqPath = "/data/Asserion_enc_no_key.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = "https://eid.a-sit.at/Shibboleth.sso/";
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ try {
+ verifyEngine.validateAssertion(inputMsg.getFirst(), credentialProvider.getMetaDataSigningCredential(),
+ spEntityId, "jUnit Test", false);
+ org.junit.Assert.fail("Wrong date not detected");
+
+ } catch (final SamlAssertionValidationExeption e) {
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.16", ((EaafException) e).getErrorId());
+
+ }
+ }
+
+ @Test
+ public void verifyEncAssertion() throws Exception {
+ final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/";
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final Response response = inputMsg.getFirst();
+ response.getAssertions().get(0).getConditions().setNotBefore(DateTime.now());
+ response.getAssertions().get(0).getConditions().setNotOnOrAfter(DateTime.now().plusMinutes(5));
+
+ final Element secAssertionElement = XMLObjectSupport.marshall(response.getAssertions().get(0));
+
+ secAssertionElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xs", "http://www.w3.org/2001/XMLSchema");
+ final Assertion secAssertion = (Assertion) XMLObjectSupport.getUnmarshaller(secAssertionElement)
+ .unmarshall(secAssertionElement);
+
+ final EncryptedAssertion encAsserton = doEncryption(secAssertion,
+ credentialProvider.getMetaDataSigningCredential(),
+ authConfig);
+ response.getEncryptedAssertions().add(encAsserton);
+
+
+ verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(),
+ spEntityId, "jUnit Test", false);
+
+ org.junit.Assert.assertEquals("Assertions not match", 2, response.getAssertions().size());
+
+ }
+
+ @Test
+ public void verifyEncAssertionWrongSchema() throws Exception {
+ final String authnReqPath = "/data/Response_without_sig_classpath_entityid.xml";
+ final String metadataPath = "classpath:/data/pvp_metadata_junit_keystore.xml";
+ final String spEntityId = "https://demo.egiz.gv.at/demoportal_demologin/";
+
+ final Pair<Response, IPvp2MetadataProvider> inputMsg =
+ initializeResponse(spEntityId, metadataPath, authnReqPath,
+ credentialProvider.getMetaDataSigningCredential());
+
+ final Response response = inputMsg.getFirst();
+ response.getAssertions().get(0).getConditions().setNotBefore(DateTime.now());
+ response.getAssertions().get(0).getConditions().setNotOnOrAfter(DateTime.now().plusMinutes(5));
+
+ final Element secAssertionElement = XMLObjectSupport.marshall(response.getAssertions().get(0));
+
+ final Assertion secAssertion = (Assertion) XMLObjectSupport.getUnmarshaller(secAssertionElement)
+ .unmarshall(secAssertionElement);
+
+ final EncryptedAssertion encAsserton = doEncryption(secAssertion,
+ credentialProvider.getMetaDataSigningCredential(),
+ authConfig);
+ response.getEncryptedAssertions().add(encAsserton);
+
+ try {
+ verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(),
+ spEntityId, "jUnit Test", false);
+
+ org.junit.Assert.fail("Wrong XML Schema not detected");
+
+ } catch (final SamlAssertionValidationExeption e) {
+ org.junit.Assert.assertEquals("Wrong errorcode", "internal.pvp.15", ((EaafException) e).getErrorId());
+
+ }
+
+ }
+
+ private Pair<Response, IPvp2MetadataProvider> initializeResponse(String spEntityId, String metadataPath,
+ String authnReqPath, EaafX509Credential credential)
+ throws SamlSigningException, XMLParserException, UnmarshallingException, Pvp2MetadataException {
+ final IPvp2MetadataProvider mdResolver = metadataResolverFactory.createMetadataProvider(
+ metadataPath, null, "jUnit metadata resolver", null);
+
+ final Response authnReq = (Response) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ SamlVerificationEngineTest.class.getResourceAsStream(authnReqPath));
+ authnReq.setIssueInstant(DateTime.now());
+ final Issuer issuer = Saml2Utils.createSamlObject(Issuer.class);
+ issuer.setValue(spEntityId);
+ authnReq.setIssuer(issuer);
+
+ return Pair.newInstance(
+ Saml2Utils.signSamlObject(authnReq, credential, true),
+ mdResolver);
+ }
+
+ private Pair<AuthnRequest, IPvp2MetadataProvider> initializeAuthnRequest(String spEntityId,
+ String metadataPath, String authnReqPath, EaafX509Credential credential)
+ throws SamlSigningException, CredentialsNotAvailableException,
+ XMLParserException, UnmarshallingException, Pvp2InternalErrorException, Pvp2MetadataException {
+
+ final IPvp2MetadataProvider mdResolver = metadataResolverFactory.createMetadataProvider(
+ metadataPath, null, "jUnit metadata resolver", null);
+
+ final AuthnRequest authnReq = (AuthnRequest) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ SamlVerificationEngineTest.class.getResourceAsStream(authnReqPath));
+ authnReq.setIssueInstant(DateTime.now());
+ final Issuer issuer = Saml2Utils.createSamlObject(Issuer.class);
+ issuer.setValue(spEntityId);
+ authnReq.setIssuer(issuer);
+
+ return Pair.newInstance(
+ Saml2Utils.signSamlObject(authnReq, credential, true),
+ mdResolver);
+
+ }
+
+ private static EncryptedAssertion doEncryption(Assertion assertion,
+ X509Credential encryptionCredentials, IConfiguration authConfig)
+ throws Exception {
+ try {
+ final String keyEncAlg = Saml2Utils.getKeyOperationAlgorithmFromCredential(
+ encryptionCredentials,
+ authConfig.getBasicConfiguration(
+ PvpConstants.CONFIG_PROP_SEC_ENCRYPTION_KEY_RSA_ALG,
+ PvpConstants.DEFAULT_ASYM_ENCRYPTION_METHODE_RSA),
+ authConfig.getBasicConfiguration(
+ PvpConstants.CONFIG_PROP_SEC_ENCRYPTION_KEY_EC_ALG,
+ PvpConstants.DEFAULT_ASYM_ENCRYPTION_METHODE_EC));
+
+ final DataEncryptionParameters dataEncParams = new DataEncryptionParameters();
+ dataEncParams.setAlgorithm(authConfig.getBasicConfiguration(
+ PvpConstants.CONFIG_PROP_SEC_ENCRYPTION_DATA, PvpConstants.DEFAULT_SYM_ENCRYPTION_METHODE));
+
+ final List<KeyEncryptionParameters> keyEncParamList = new ArrayList<>();
+ final KeyEncryptionParameters keyEncParam = new KeyEncryptionParameters();
+ keyEncParam.setEncryptionCredential(encryptionCredentials);
+ keyEncParam.setAlgorithm(keyEncAlg);
+
+ final KeyInfoGeneratorFactory kigf =
+ SecurityConfigurationSupport.getGlobalEncryptionConfiguration()
+ .getKeyTransportKeyInfoGeneratorManager().getDefaultManager().getFactory(encryptionCredentials);
+ keyEncParam.setKeyInfoGenerator(kigf.newInstance());
+ keyEncParamList.add(keyEncParam);
+
+ final Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList);
+ samlEncrypter.setKeyPlacement(KeyPlacement.PEER);
+
+ return samlEncrypter.encrypt(assertion);
+
+ } catch (final EncryptionException | SamlSigningException e1) {
+ throw new Exception(e1);
+
+ }
+
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java
index 76dba510..8833202a 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/PostBindingTest.java
@@ -9,27 +9,6 @@ import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
-import at.gv.egiz.eaaf.core.api.IRequest;
-import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiBuilderConfiguration;
-import at.gv.egiz.eaaf.core.impl.idp.module.gui.DummyGuiBuilderConfigurationFactory;
-import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
-import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
-import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory;
-import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
-import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface;
-import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
-import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
-import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
-import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
-import at.gv.egiz.eaaf.modules.pvp2.exception.SamlMessageValidationException;
-import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
-import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding;
-import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
-import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
-import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare;
-import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
-import at.gv.egiz.eaaf.modules.pvp2.test.metadata.MetadataResolverTest;
-
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.joda.time.DateTime;
@@ -38,14 +17,19 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.opensaml.core.xml.XMLObject;
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.core.xml.io.MarshallingException;
import org.opensaml.core.xml.io.Unmarshaller;
import org.opensaml.core.xml.io.UnmarshallerFactory;
import org.opensaml.core.xml.io.UnmarshallingException;
+import org.opensaml.core.xml.schema.XSString;
import org.opensaml.core.xml.util.XMLObjectSupport;
import org.opensaml.messaging.decoder.MessageDecodingException;
import org.opensaml.messaging.encoder.MessageEncodingException;
import org.opensaml.saml.common.SignableSAMLObject;
+import org.opensaml.saml.saml2.core.AuthnRequest;
+import org.opensaml.saml.saml2.core.Issuer;
import org.opensaml.saml.saml2.core.RequestAbstractType;
import org.opensaml.saml.saml2.core.StatusResponseType;
import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
@@ -58,7 +42,34 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.gui.IVelocityGuiBuilderConfiguration;
+import at.gv.egiz.eaaf.core.impl.idp.module.gui.DummyGuiBuilderConfigurationFactory;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
+import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
+import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory;
+import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
+import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute;
+import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlMessageValidationException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding;
+import at.gv.egiz.eaaf.modules.pvp2.impl.message.InboundMessage;
+import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileRequest;
+import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileResponse;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
+import at.gv.egiz.eaaf.modules.pvp2.test.metadata.MetadataResolverTest;
import net.shibboleth.utilities.java.support.net.URIComparator;
+import net.shibboleth.utilities.java.support.xml.SerializeSupport;
import net.shibboleth.utilities.java.support.xml.XMLParserException;
import okhttp3.HttpUrl;
import okhttp3.mockwebserver.MockResponse;
@@ -125,6 +136,34 @@ public class PostBindingTest {
}
@Test
+ public void wrongPostBindingEncoding() throws MessageDecodingException, SecurityException,
+ IOException, Pvp2MetadataException {
+ final String serviceUrl = "https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp2/post";
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_wrong_sig.xml", null, "jUnit metadata resolver", null);
+
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ final String b64AuthnReq = Base64.getEncoder().encodeToString(IOUtils.toByteArray(
+ PostBindingTest.class.getResourceAsStream("/data/AuthRequest_without_sig_1.xml")));
+ httpReq.setMethod("POST");
+ httpReq.addParameter("SAMLRequest", b64AuthnReq);
+ httpReq.setParameter("SAMLEncoding", RandomStringUtils.randomAlphabetic(5));
+
+ try {
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator);
+ Assert.fail("Missing signature not detected");
+
+ } catch (final Pvp2Exception e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.02", e.getErrorId());
+
+ }
+
+ }
+
+ @Test
public void decodeRequestWrongEndpoint() throws MessageDecodingException, SecurityException,
IOException, Pvp2MetadataException {
final String serviceUrl = "https://wrongEndpoint/pvp2/post";
@@ -315,6 +354,73 @@ public class PostBindingTest {
}
@Test
+ public void decodeRequestSuccessWithRequestAttributes() throws MessageDecodingException, SecurityException,
+ IOException, Pvp2Exception, CredentialsNotAvailableException, XMLParserException, UnmarshallingException, MarshallingException {
+ final String serviceUrl = "https://eidas-test.bmi.gv.at/ms_connector/pvp/post";
+ final String relayState = RandomStringUtils.randomAlphanumeric(10);
+
+ final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ PostBindingTest.class.getResourceAsStream("/data/eIDAS_connector_authn.xml"));
+ authnReq.setIssueInstant(DateTime.now());
+ Issuer issuer = Saml2Utils.createSamlObject(Issuer.class);
+ issuer.setValue("https://demo.egiz.gv.at/demoportal_demologin/");
+ authnReq.setIssuer(issuer);
+
+ RequestAbstractType signedAuthn = Saml2Utils.signSamlObject(authnReq, credentialProvider.getMessageSigningCredential(), true);
+ Element signedElement = XMLObjectSupport.getMarshaller(signedAuthn).marshall(signedAuthn);
+ final String b64AuthnReq =
+ Base64.getEncoder().encodeToString(SerializeSupport.nodeToString(signedElement).getBytes("UTF-8"));
+ httpReq.setMethod("POST");
+ httpReq.addParameter("SAMLRequest", b64AuthnReq);
+ httpReq.addParameter("RelayState", relayState);
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null);
+
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ final InboundMessageInterface msg =
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator);
+
+ Assert.assertNotNull("PVP msg is null", msg);
+ Assert.assertNotNull("RelayState is not null", msg.getRelayState());
+ Assert.assertEquals("RelayState not match", relayState, msg.getRelayState());
+ Assert.assertNotNull("AuthnReq is null", msg.getInboundMessage());
+ Assert.assertNotNull("EntityId is null", msg.getEntityID());
+ Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg.getEntityID());
+ Assert.assertTrue("Wrong isVerified flag", msg.isVerified());
+
+ org.springframework.util.Assert.isInstanceOf(PvpSProfileRequest.class, msg, "Inbound message is of wrong type");
+ org.springframework.util.Assert.isInstanceOf(AuthnRequest.class, ((PvpSProfileRequest)msg).getSamlRequest(),
+ "Inbound message is of wrong type");
+
+ AuthnRequest parsedAuthnReq = (AuthnRequest)((PvpSProfileRequest)msg).getSamlRequest();
+ Assert.assertNotNull("No extension", parsedAuthnReq.getExtensions());
+ Assert.assertNotNull("No extension child", parsedAuthnReq.getExtensions().getUnknownXMLObjects());
+ Assert.assertEquals("extension child size", 1, parsedAuthnReq.getExtensions().getUnknownXMLObjects().size());
+
+ XMLObject reqAttrs = parsedAuthnReq.getExtensions().getUnknownXMLObjects().get(0);
+ org.springframework.util.Assert.isInstanceOf(EaafRequestedAttributes.class, reqAttrs, "Wrong requested Attributes type");
+ EaafRequestedAttributes eaafReqAttrs = (EaafRequestedAttributes) reqAttrs;
+ Assert.assertNotNull("Req attr is null", eaafReqAttrs.getAttributes());
+ Assert.assertFalse("Req attr is empty", eaafReqAttrs.getAttributes().isEmpty());
+ Assert.assertEquals("Req attr size", 1, eaafReqAttrs.getAttributes().size());
+
+ EaafRequestedAttribute eaafReqAttr = eaafReqAttrs.getAttributes().get(0);
+ Assert.assertNotNull("Req Attibute is null", eaafReqAttr);
+ Assert.assertEquals("Req. Attr. Friendlyname", "EID-SECTOR-FOR-IDENTIFIER", eaafReqAttr.getFriendlyName());
+ Assert.assertEquals("Req. Attr. Name", "urn:oid:1.2.40.0.10.2.1.1.261.34", eaafReqAttr.getName());
+
+ Assert.assertEquals("Req. Attr. Value size", 1, eaafReqAttr.getAttributeValues().size());
+ org.springframework.util.Assert.isInstanceOf(XSString.class, eaafReqAttr.getAttributeValues().get(0),
+ "Wrong requested Attributes Value type");
+ Assert.assertEquals("Req. Attr. Value", "urn:publicid:gv.at:cdid+BF", ((XSString)eaafReqAttr.getAttributeValues().get(0)).getValue());
+
+ }
+
+ @Test
public void decodeRequestSuccessWithoutRelayStateEcdsaSig() throws MessageDecodingException, SecurityException,
IOException, Pvp2Exception, CredentialsNotAvailableException, XMLParserException, UnmarshallingException {
final String serviceUrl = "http://testservice.org";
@@ -340,6 +446,13 @@ public class PostBindingTest {
Assert.assertNotNull("EntityId is null", msg.getEntityID());
Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg.getEntityID());
Assert.assertTrue("Wrong isVerified flag", msg.isVerified());
+
+ //check if reconstraction from serialized form work well
+ ((InboundMessage)msg).setSamlMessage(null);
+ try {
+ Assert.assertNotNull("AuthnReq is null", msg.getInboundMessage());
+
+ } catch (RuntimeException e) { }
}
@@ -367,6 +480,8 @@ public class PostBindingTest {
Assert.assertNotNull("EntityId is null", msg.getEntityID());
Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg.getEntityID());
Assert.assertTrue("Wrong isVerified flag", msg.isVerified());
+
+ org.springframework.util.Assert.isInstanceOf(PvpSProfileResponse.class, msg, "Inbound message is of wrong type");
}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java
index f85e5c2a..408729e3 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/binding/RedirectBindingTest.java
@@ -2,36 +2,15 @@ package at.gv.egiz.eaaf.modules.pvp2.test.binding;
import java.io.IOException;
import java.net.URLDecoder;
-import java.util.Base64;
import javax.xml.parsers.ParserConfigurationException;
-import at.gv.egiz.eaaf.core.api.IRequest;
-import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
-import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory;
-import at.gv.egiz.eaaf.modules.pvp2.PvpConstants;
-import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
-import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface;
-import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
-import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
-import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
-import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
-import at.gv.egiz.eaaf.modules.pvp2.exception.SamlMessageValidationException;
-import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
-import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding;
-import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
-import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
-import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare;
-import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
-import at.gv.egiz.eaaf.modules.pvp2.test.metadata.MetadataResolverTest;
-
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
@@ -50,6 +29,24 @@ import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.xml.sax.SAXException;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
+import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory;
+import at.gv.egiz.eaaf.modules.pvp2.PvpConstants;
+import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
+import at.gv.egiz.eaaf.modules.pvp2.api.message.InboundMessageInterface;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlMessageValidationException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
+import at.gv.egiz.eaaf.modules.pvp2.test.metadata.MetadataResolverTest;
import net.shibboleth.utilities.java.support.net.URIComparator;
import net.shibboleth.utilities.java.support.net.URISupport;
import net.shibboleth.utilities.java.support.xml.XMLParserException;
@@ -129,6 +126,93 @@ public class RedirectBindingTest {
}
@Test
+ public void wrongHttpRequestMethod() throws MessageDecodingException,
+ SecurityException, IOException, Pvp2MetadataException {
+ final String serviceUrl = "http://testservice.org";
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_wrong_sig.xml", null, "jUnit metadata resolver", null);
+
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ httpReq.setMethod("POST");
+ httpReq.setRequestURI("http://testservice.org");
+ httpReq.setQueryString("SAMLRequest=nVRNb9swDD13wP6DoXvkr%2FRjQuzCSFAgQDd0TbfDLoVi0642Wcok2kn766c4duABWw%"
+ + "2B%2BSdQj%2BfhIanF7qKXXgrFCq4SENCAeqFwXQlUJ%2BfZ0N7sht%2BnC8lpGO5Y1%2BKIe4XcDFj3nqCw7vSSkMYppboVli"
+ + "tdgGeZsk32%2BZxEN2M5o1LmWxMusBYMu1VIr29RgNmBakcNaFXBw6R0C0Yhtg3BCOBp%2FQxy%2FlcsuFMeO8Qvijvk%2BOps"
+ + "9Aak2FfHWq4Q8c4BtySHO4eomLCEuipyXURjzeVQGYRE7mLWNC22RK0xIFITzWRDPgsun4IrFn1gQ0evryx%2FE%2Bz4o5Oohv"
+ + "R6sczZjId7XgQ%2FVE%2B9Om5rj%2B%2FCjRRSzsoMyUCjwlaTHgq2ruIBaU6jEG61ayrG777RBLp%2BPR6krofyFP2Y68N402"
+ + "5%2BQ4xTi6ccPFxd9mC8Ot15NI9T7umiDpSd1nrUT4kFLkb96mZR6vzTAERKCpoEpCu6OPbTohCRThtc%2FU%2Bs3AIpuH9ygI"
+ + "hwm7cNYzXGspXSKP0I5qUP9Ruz3e2pRm1%2B00i2Fxne77ecCxRuor1l2Dy1Ifz6o%2F6%2Fso%2B78p%2Bb0%2FDz%2BGdI%2"
+ + "F&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&Signature=DOVMqh17xn4wl%2"
+ + "Byvifm4McMsBjKDVf1eqph9ss362ZEbp2nkAIXUzkNWv72I96iNK3r%2BYbAxY9dwZ8Z7jKzCGiJ9Qm34YSfPvzXWl3EVrdI86"
+ + "9U%2BH6HGIMqVew3cVdr4q3Qv9ZBIhdRxbrDu%2F%2BnMjdf8mzbgcQnfjSQiQIYWxOIXZFyxKsyrxJtIam4hoNwUT7mMN6Rjg"
+ + "zvyeS3mARsTJdcI0Vn4ItiprhLgIkD18V9WIdeSZR0gfRaFj8PKdmXCD%2FIa0cKgjhVKoiIZisV4vcthBOeDIqBORL2Ad3Xhc"
+ + "NRQ3%2BcpAf65zHGMBAv1aRy7Bmv0%2B%2BOvCavufykqI2EHtg%3D%3D");
+
+ httpReq.setParameter(HTTP_FORM_SAMLREQ, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_FORM_SAMLREQ).substring(HTTP_FORM_SAMLREQ_PARAM.length()), "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGALG, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGALG).substring(HTTP_REDIRECT_SIGALG_PARAM.length()),
+ "UTF-8"));
+
+ try {
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME,
+ comparator);
+ Assert.fail("Missing signature not detected");
+
+ } catch (final Pvp2Exception e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.95", e.getErrorId());
+
+ }
+ }
+
+ @Test
+ public void wrongRedirectBindingType() throws MessageDecodingException,
+ SecurityException, IOException, Pvp2MetadataException {
+ final String serviceUrl = "http://testservice.org";
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_wrong_sig.xml", null, "jUnit metadata resolver", null);
+
+ final URIComparator comparator = new EaafUriCompare(serviceUrl);
+
+ httpReq.setMethod("POST");
+ httpReq.setRequestURI("http://testservice.org");
+ httpReq.setQueryString("SAMLRequest=nVRNb9swDD13wP6DoXvkr%2FRjQuzCSFAgQDd0TbfDLoVi0642Wcok2kn766c4duABWw%"
+ + "2B%2BSdQj%2BfhIanF7qKXXgrFCq4SENCAeqFwXQlUJ%2BfZ0N7sht%2BnC8lpGO5Y1%2BKIe4XcDFj3nqCw7vSSkMYppboVli"
+ + "tdgGeZsk32%2BZxEN2M5o1LmWxMusBYMu1VIr29RgNmBakcNaFXBw6R0C0Yhtg3BCOBp%2FQxy%2FlcsuFMeO8Qvijvk%2BOps"
+ + "9Aak2FfHWq4Q8c4BtySHO4eomLCEuipyXURjzeVQGYRE7mLWNC22RK0xIFITzWRDPgsun4IrFn1gQ0evryx%2FE%2Bz4o5Oohv"
+ + "R6sczZjId7XgQ%2FVE%2B9Om5rj%2B%2FCjRRSzsoMyUCjwlaTHgq2ruIBaU6jEG61ayrG777RBLp%2BPR6krofyFP2Y68N402"
+ + "5%2BQ4xTi6ccPFxd9mC8Ot15NI9T7umiDpSd1nrUT4kFLkb96mZR6vzTAERKCpoEpCu6OPbTohCRThtc%2FU%2Bs3AIpuH9ygI"
+ + "hwm7cNYzXGspXSKP0I5qUP9Ruz3e2pRm1%2B00i2Fxne77ecCxRuor1l2Dy1Ifz6o%2F6%2Fso%2B78p%2Bb0%2FDz%2BGdI%2"
+ + "F&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&Signature=DOVMqh17xn4wl%2"
+ + "Byvifm4McMsBjKDVf1eqph9ss362ZEbp2nkAIXUzkNWv72I96iNK3r%2BYbAxY9dwZ8Z7jKzCGiJ9Qm34YSfPvzXWl3EVrdI86"
+ + "9U%2BH6HGIMqVew3cVdr4q3Qv9ZBIhdRxbrDu%2F%2BnMjdf8mzbgcQnfjSQiQIYWxOIXZFyxKsyrxJtIam4hoNwUT7mMN6Rjg"
+ + "zvyeS3mARsTJdcI0Vn4ItiprhLgIkD18V9WIdeSZR0gfRaFj8PKdmXCD%2FIa0cKgjhVKoiIZisV4vcthBOeDIqBORL2Ad3Xhc"
+ + "NRQ3%2BcpAf65zHGMBAv1aRy7Bmv0%2B%2BOvCavufykqI2EHtg%3D%3D");
+
+ httpReq.setParameter(HTTP_FORM_SAMLREQ, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_FORM_SAMLREQ).substring(HTTP_FORM_SAMLREQ_PARAM.length()), "UTF-8"));
+ httpReq.setParameter(HTTP_REDIRECT_SIGALG, URLDecoder.decode(URISupport.getRawQueryStringParameter(
+ httpReq.getQueryString(), HTTP_REDIRECT_SIGALG).substring(HTTP_REDIRECT_SIGALG_PARAM.length()),
+ "UTF-8"));
+ httpReq.setParameter("SAMLEncoding", RandomStringUtils.randomAlphabetic(5));
+
+ try {
+ bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME,
+ comparator);
+ Assert.fail("Missing signature not detected");
+
+ } catch (final Pvp2Exception e) {
+ Assert.assertEquals("Wrong errorCode", "internal.pvp.95", e.getErrorId());
+
+ }
+ }
+
+ @Test
public void decodeRequestNoSignature() throws MessageDecodingException,
SecurityException, IOException, Pvp2MetadataException {
final String serviceUrl = "http://testservice.org";
@@ -169,7 +253,6 @@ public class RedirectBindingTest {
Assert.assertEquals("Wrong errorCode", "internal.pvp.02", e.getErrorId());
}
-
}
@Test
@@ -362,38 +445,6 @@ public class RedirectBindingTest {
}
- @Ignore
- @Test
- public void decodeRequestSuccessWithRelayState() throws MessageDecodingException,
- SecurityException, IOException, Pvp2Exception {
- final String serviceUrl = "http://testservice.org";
- final String relayState = RandomStringUtils.randomAlphanumeric(10);
-
- final String b64AuthnReq = Base64.getEncoder().encodeToString(IOUtils.toByteArray(
- RedirectBindingTest.class.getResourceAsStream("/data/AuthRequest_with_sig_1.xml")));
- httpReq.setMethod("POST");
- httpReq.addParameter("SAMLRequest", b64AuthnReq);
- httpReq.addParameter("RelayState", relayState);
-
- final IPvp2MetadataProvider metadataProvider = null;
-
- final URIComparator comparator = new EaafUriCompare(serviceUrl);
-
- final InboundMessageInterface msg =
- bindingImpl.decode(httpReq, httpResp, metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME,
- comparator);
-
- Assert.assertNotNull("PVP msg is null", msg);
- Assert.assertNotNull("RelayState is not null", msg.getRelayState());
- Assert.assertEquals("RelayState not match", relayState, msg.getRelayState());
- Assert.assertNotNull("AuthnReq is null", msg.getInboundMessage());
- Assert.assertNotNull("EntityId is null", msg.getEntityID());
- Assert.assertEquals("EntityId not match", "https://demo.egiz.gv.at/demoportal_demologin/", msg
- .getEntityID());
- Assert.assertFalse("Wrong isVerified flag", msg.isVerified());
-
- }
-
@Test
public void decodeResponseSuccess() throws MessageDecodingException, SecurityException, IOException,
Pvp2Exception, CredentialsNotAvailableException, XMLParserException, UnmarshallingException {
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/dummy/DummyMetadataProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/dummy/DummyMetadataProvider.java
new file mode 100644
index 00000000..64ebe00c
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/dummy/DummyMetadataProvider.java
@@ -0,0 +1,80 @@
+package at.gv.egiz.eaaf.modules.pvp2.test.dummy;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.List;
+
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.AbstractChainingMetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+
+import org.opensaml.saml.metadata.resolver.MetadataResolver;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilter;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DummyMetadataProvider extends AbstractChainingMetadataProvider {
+
+ private final List<String> configuredMetadataUrls = new ArrayList<>();
+ private String metadataProviderName;
+
+ @Autowired PvpMetadataResolverFactory resolverFactory;
+ @Autowired IHttpClientFactory httpClientFactory;
+ private final MetadataFilterChain metadataFilters = new MetadataFilterChain();
+
+ @Override
+ protected String getMetadataUrl(String entityId) throws EaafConfigurationException {
+ return entityId;
+
+ }
+
+ @Override
+ protected MetadataResolver createNewMetadataProvider(String entityId) throws EaafConfigurationException,
+ IOException, CertificateException {
+ try {
+ return resolverFactory.createMetadataProvider(entityId, metadataFilters, entityId, null,
+ httpClientFactory.getHttpClient());
+
+ } catch (final Pvp2MetadataException e) {
+ throw new EaafConfigurationException("internal.pvp.04", new Object[] {entityId}, e);
+
+ }
+
+ }
+
+ @Override
+ protected List<String> getAllMetadataUrlsFromConfiguration() throws EaafConfigurationException {
+ return configuredMetadataUrls;
+
+ }
+
+ @Override
+ protected String getMetadataProviderId() {
+ return metadataProviderName;
+
+ }
+
+ public void addMetadataUrls(List<String> metadataUrls) {
+ configuredMetadataUrls.addAll(metadataUrls);
+
+ }
+
+ public void clearMetadataUrls() {
+ configuredMetadataUrls.clear();
+
+ }
+
+ public void setMetadataProviderName(String name) {
+ metadataProviderName = name;
+
+ }
+
+ public void setMetadataFilters(List<MetadataFilter> filtersToUse) {
+ metadataFilters.setFilters(filtersToUse);
+
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/ChainingMetadataTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/ChainingMetadataTest.java
new file mode 100644
index 00000000..8e00068f
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/ChainingMetadataTest.java
@@ -0,0 +1,166 @@
+package at.gv.egiz.eaaf.modules.pvp2.test.metadata;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.impl.utils.FileUtils;
+import at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyMetadataProvider;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opensaml.core.criterion.EntityIdCriterion;
+import org.opensaml.saml.criterion.EntityRoleCriterion;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+import okhttp3.HttpUrl;
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration({ "/spring/test_eaaf_pvp.beans.xml",
+ "/spring/test_eaaf_core_spring_config.beans.xml" })
+@TestPropertySource(locations = { "/config/config_1.props" })
+public class ChainingMetadataTest {
+
+ private static MockWebServer mockWebServer;
+ private static HttpUrl mockServerUrl;
+
+ @Autowired DummyMetadataProvider metadataProvider;
+ @Autowired PvpMetadataResolverFactory factory;
+ @Autowired IConfiguration authConfig;
+ @Autowired IHttpClientFactory httpFactory;
+
+
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void classInitializer() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ mockWebServer = new MockWebServer();
+ mockServerUrl = mockWebServer.url("/sp/metadata");
+ }
+
+ @Test
+ public void runGarbageCollector() throws ResolverException, Pvp2MetadataException,
+ UnsupportedEncodingException, IOException {
+
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(new String(IOUtils.toByteArray(
+ MetadataResolverTest.class.getResourceAsStream(
+ "/data/pvp_metadata_moaid_test.xml")), "UTF-8"))
+ .setHeader("Content-Type", "text/xml"));
+
+ final EntityDescriptor entityDesc =
+ metadataProvider.getEntityDescriptor("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml");
+ Assert.assertNotNull("EntityDesc is null", entityDesc);
+
+ final IPvp2MetadataProvider provider2 = factory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit", null);
+ metadataProvider.addMetadataResolverIntoChain(provider2);
+
+ final IPvp2MetadataProvider provider3 = factory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_valid_with_entityCategory_egov.xml", null, "jUnit", null);
+ metadataProvider.addMetadataResolverIntoChain(provider3);
+
+ final IPvp2MetadataProvider provider4 = factory.createMetadataProvider(
+ mockServerUrl.url().toString(), null, "jUnit", httpFactory.getHttpClient());
+ metadataProvider.addMetadataResolverIntoChain(provider4);
+
+
+
+
+ metadataProvider.addMetadataUrls(Arrays.asList(
+ FileUtils.makeAbsoluteUrl("classpath:/data/pvp_metadata_junit_keystore.xml",
+ authConfig.getConfigurationRootDirectory()), mockServerUrl.url().toString()));
+
+ metadataProvider.runGarbageCollector();
+
+ final EntityDescriptor entityDesc4 =
+ metadataProvider.getEntityDescriptor("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml");
+ Assert.assertNotNull("EntityDesc is null", entityDesc4);
+
+
+ metadataProvider.clearMetadataUrls();
+ metadataProvider.runGarbageCollector();
+
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(new EntityIdCriterion("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"));
+ final EntityDescriptor entityDesc5 = metadataProvider.resolveSingle(criteria);
+ Assert.assertNotNull("EntityDesc is null", entityDesc5);
+
+
+ final CriteriaSet criteria6 = new CriteriaSet();
+ criteria6.add(new EntityIdCriterion("classpath:/data/classpath:/data/pvp_metadata_junit_keystore.xml"));
+ final EntityDescriptor entityDesc6 = metadataProvider.resolveSingle(criteria6);
+ Assert.assertNull("EntityDesc not null", entityDesc6);
+
+ metadataProvider.refreshMetadataProvider("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml");
+
+ metadataProvider.clear();
+
+ metadataProvider.refreshMetadataProvider("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml");
+
+ metadataProvider.clear("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml");
+
+ Assert.assertFalse("Wrong refresh flag", metadataProvider.wasLastRefreshSuccess());
+
+ metadataProvider.getMetadataFilter();
+
+ metadataProvider.fullyDestroy();
+
+ metadataProvider.refreshMetadataProvider("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml");
+
+ final CriteriaSet criteria7 = new CriteriaSet();
+ criteria7.add(new EntityIdCriterion("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml"));
+ final Iterable<EntityDescriptor> entityDesc7 = metadataProvider.resolve(criteria7);
+ Assert.assertNotNull("EntityDesc is null", entityDesc7);
+ Assert.assertTrue("is Empty", entityDesc7.iterator().hasNext());
+
+ final CriteriaSet criteria8 = new CriteriaSet();
+ criteria8.add(new EntityIdCriterion("classpath:/data/classpath:/data/pvp_metadata_junit_keystore.xml"));
+ final Iterable<EntityDescriptor> entityDesc8 = metadataProvider.resolve(criteria8);
+ Assert.assertNotNull("EntityDesc not null", entityDesc8);
+ Assert.assertFalse("is not Empty", entityDesc8.iterator().hasNext());
+
+ metadataProvider.refresh();
+
+ metadataProvider.getLastRefresh();
+
+ metadataProvider.getLastSuccessfulRefresh();
+
+ metadataProvider.getLastUpdate();
+
+ metadataProvider.refreshMetadataProvider("classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml");
+
+
+ final CriteriaSet criteria9 = new CriteriaSet();
+ criteria9.add(new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME));
+ final Iterable<EntityDescriptor> entityDesc9 = metadataProvider.resolve(criteria9);
+ Assert.assertNotNull("EntityDesc not null", entityDesc9);
+
+ }
+
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataBuilderTest.java b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataBuilderTest.java
index f8402510..6cf81d2b 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataBuilderTest.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/java/at/gv/egiz/eaaf/modules/pvp2/test/metadata/MetadataBuilderTest.java
@@ -14,14 +14,6 @@ import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactoryConfigurationError;
-import at.gv.egiz.eaaf.core.exceptions.EaafException;
-import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
-import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration;
-import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
-import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder;
-import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
-import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
-
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Assert;
import org.junit.BeforeClass;
@@ -49,6 +41,14 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.api.utils.IPvp2CredentialProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
import net.shibboleth.utilities.java.support.xml.XMLParserException;
@@ -84,7 +84,7 @@ public class MetadataBuilderTest {
TransformerException, ParserConfigurationException, IOException, SignatureException,
XMLParserException, UnmarshallingException, CertificateException {
- final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(false, true);
+ final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(credentialProvider, false, true);
//generate metadata
final String metadata = metadataBuilder.buildPvpMetadata(config);
@@ -102,7 +102,7 @@ public class MetadataBuilderTest {
TransformerException, ParserConfigurationException, IOException, SignatureException,
XMLParserException, UnmarshallingException, CertificateException {
- final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(true, false);
+ final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(credentialProvider, true, false);
//generate metadata
final String metadata = metadataBuilder.buildPvpMetadata(config);
@@ -120,7 +120,7 @@ public class MetadataBuilderTest {
TransformerException, ParserConfigurationException, IOException, SignatureException,
XMLParserException, UnmarshallingException, CertificateException {
- final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(true, true);
+ final IPvpMetadataBuilderConfiguration config = idpMetadataConfig(credentialProvider, true, true);
//generate metadata
final String metadata = metadataBuilder.buildPvpMetadata(config);
@@ -155,7 +155,7 @@ public class MetadataBuilderTest {
return entity;
}
- private IPvpMetadataBuilderConfiguration idpMetadataConfig(boolean buildSpInfos, boolean buildIdpInfos) {
+ public static IPvpMetadataBuilderConfiguration idpMetadataConfig(IPvp2CredentialProvider credentialProvider, boolean buildSpInfos, boolean buildIdpInfos) {
return new IPvpMetadataBuilderConfiguration() {
@Override
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/Asserion_enc_no_key.xml b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/Asserion_enc_no_key.xml
new file mode 100644
index 00000000..a1428347
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/Asserion_enc_no_key.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response Destination="https://eid.a-sit.at/Shibboleth.sso/SAML2/POST" ID="_d4c5806eb9d7aec2a37541184023d38d" InResponseTo="_f9db5e7b5ddfd119edc3f9b63b086071" IssueInstant="2020-02-05T13:06:55.691Z" Version="2.0" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://eid.a-sit.at/idp/shibboleth</saml2:Issuer>
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:SignedInfo>
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/>
+ <ds:Reference URI="#_d4c5806eb9d7aec2a37541184023d38d">
+ <ds:Transforms>
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ </ds:Transforms>
+ <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/>
+ <ds:DigestValue>InYZAEShnT3qk+4LlRpjt+nxCQAnerLIMQpoMzT8/SQ8E8vG36c06b4pjnjUa91p4ehdn1NSV52+9GlbXCBp8Q==</ds:DigestValue>
+ </ds:Reference>
+ </ds:SignedInfo>
+ <ds:SignatureValue>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE=</ds:SignatureValue>
+ <ds:KeyInfo>
+ <ds:X509Data>
+ <ds:X509Certificate>MIIDBzCCAq2gAwIBAgIINiXH097lKl4wCgYIKoZIzj0EAwIwGjEYMBYGA1UEAwwPTG9jYWxQa2lT
+ZXJ2aWNlMB4XDTIwMDIwNTEyMjQyOVoXDTIwMDUwNTExMjQyOVowLjEZMBcGA1UEAwwQN2xXOUps
+S2FYRW93eDJFYzERMA8GA1UECgwIc29mdHdhcmUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQDCOl3IYslq+HV1/FlSJxCdzKJ439pM98U+UfJ+bMEI6k/heFS/MNCsDDiWbIpeD2G8mDss
+N1dl5xKvhgBaibYoKCjNS/sToOzhUVNfIdy/S9fc74nrXsaHB1sAf33L/2srpE2dTy/KQKAqtZ7M
+eSC3GRnIyqb6KWBDSNItQ0o/6EGn+enFSkTiZM/WUWfMhe46vCVF2QWV6NvRv64xMJtYsC3dHiGs
+xYgG9uZitcs0dfsY/DH4xr/vd3g5uioTDs5PElFrvzx4lbpsWMRy5OmfCRvt0R+VXP53+9o6xvNg
+TbkV9rh54xwzf6geqMxT7S9na7/YzCq4hg9V4FkYCZfvXXazcxJeUNTChhvKBBXozia+FnDM67/s
+QlTW2ZhGzTWv/Zs1a1xA65qahJuDeHVKo6fagAGlYNNFXNDbzPdpydtbj+5vF8dnpMp9fC9nPeQD
+8BF3DOA4vraNET4XraX/vaWkvaKVCtoWYnX510TbMqtwLmksq2KiIe4mEcuEINhQ/3ERwH0mwn+/
+LKVVBRdN0gucMTSlglFe0ctuyDb8sId5kGxxucwjFBjqsRSCXpHEjlydFE0fPF6slTGl0+GCJdpJ
+StDuaQ38a35U+N7x9IucakNGBXfZcwWp4dx4t8cokxLN5bpPpLo3PVfMBQ0dnH9MSzm5nVhJL5fJ
+Q1asrQIDAQABMAoGCCqGSM49BAMCA0gAMEUCIQD04k68PMq+VuwfIbIWJkg3weQUASVKxKDjHnfH
+/YsrPQIgVkmT8vTKC6YrfaAiMlFXsQGX9iDJBbnqNB3+9GUY7Z0=</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </ds:Signature>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <saml2:EncryptedAssertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
+ <xenc:EncryptedData Id="_8bfb44aaaec124f25496619c3c59daa9" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
+ <xenc:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes128-gcm" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"/>
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <xenc:EncryptedKey Id="_9af666773660a6b50b4da5879a0ed6a5" Recipient="https://eid.a-sit.at/shibboleth" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
+ <xenc:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#rsa-oaep" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
+ <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
+ <xenc11:MGF Algorithm="http://www.w3.org/2009/xmlenc11#mgf1sha1" xmlns:xenc11="http://www.w3.org/2009/xmlenc11#"/>
+ </xenc:EncryptionMethod>
+ <ds:KeyInfo>
+ <ds:X509Data>
+ <ds:X509Certificate>MIID6zCCAlOgAwIBAgIJAPoNcjesqrTTMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNVBAMTDGVpZC5h
+LXNpdC5hdDAeFw0yMDAyMDUwODQ3MjlaFw0zMDAyMDIwODQ3MjlaMBcxFTATBgNVBAMTDGVpZC5h
+LXNpdC5hdDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALxWBbZxOq06T+jUsJdpl8B2
+r6EYlY8MoNGsFDGyc/KuEALitFboBkgH0ztNS4YLGGdaTi3WPX3NZGr5zBx8bsxVvEW67mTkLSlw
+3/FWhO8oMUuBQlR21piecVZBLj91NHstkcTSD5Cbq4uBRpPKBha7b5DrCD1BvLBYto5BCsLYeNp4
+UFgBFaLP+nUpS5fOaA6IGPRPDVKkL9wxob4Md75FuuE58MdiwaByzGjNtsmYM8uTy8wnFpXvYDwj
+g3z3Pe3jrpoUglSdrFweTnXCCrkuqzjWtt5CHYW47NgrcV7hRARHFlzzBgYW2kmLnMNdhJHOldkN
+DKaqn0oV2gCaemxvWKVbSYcZ27kyYFqPWaou/o4ufvQT9P8LeFKayL10b7chEU4UbJYTjh4Pi4On
+VhOtOrguNJDd/qbcKrlHRb+DpDVHmZi5w9HDpg3l3SlGTzuib0nWZ64IG4Y8a1c2tpFRoiYv/aXu
+7JHPMRNp/LoA1qwoF19jUzV8TWZbrrPkIwIDAQABozowODAXBgNVHREEEDAOggxlaWQuYS1zaXQu
+YXQwHQYDVR0OBBYEFLP5q5ESOCfShH5tQmk6gN+PgSNSMA0GCSqGSIb3DQEBCwUAA4IBgQBHHhCl
+un9DsVkT+LSEkKwyRI90wppWRpzEg2HFhbc+G53jF/qPX2WlvAASDULzPH+uBrqdbiAUlXk1JBYc
+Ux0u6xV0mGSHdgq0eSzlLI/exjJTtsIOT8zeSTwjvhlNiXlJGSanoOUVNysIXM4Nv+NUB/MbYcVT
+xDXzYGl45qhNhCcLSD4pQmVRAuhElH/ZwNXtUjaN2x48alZTq/+hdGK+YpNqeHS8+LcqkX9Mctth
+xkF6piecW9QYzzmDlq+sOaezdhRcUS4tABaOmBFysO2GdMUtaDnBGeFiMLdRRijAEwBFYSO425pW
+9Sj9ce32RgsopRF1Sz1SbbH4COrf5LdQwzS7qEUdDXQIOP7HbO9NrXkyN3W/lp5c/uVBe5fQt8Ke
+v7jKaanqQozChmu6/iO7Y8DHj2/4o3QHfw4qjraJoGOSbqHDq4wBr8c403nnuGQzW0BWA04Cm0J1
+UAq08IPUdLQdsRtHOb+IVig/3S2PekIIl/U73OJChRg9566vwNo=</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ <xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
+ <xenc:CipherValue>ex7yi4ATGyUZmH9deZW5zwG8DGE/38pIR4hMJKQpOhxWMkwIgDmQ9AxB9qjYb7Rg7sVm6Tzeyy7cYkKvC3v5yLkCJ4JMfBSn2jmovAUW9o6m0S/IVSyzWUknIzVO5ZRK91M0TINmlo7kKeD9mtW2LNgo2Ai5mfCThjPGbkJFelHJjDCnu2IGu+3g1uif8kx5m3NAVg7vT8SrpdQSCZrsuhw7IM5OEKxtutAeLDdu8W88bkLDeaM+Oe7jKRfa25q5ZEpFWfDKnju0qIybjzGifS/nZDT0CRftFsusZ8QMoytvQ2Brget6ymH723sAjngDE+JZ6Za9U4FJH/8P2n7Fs91i1QCPMbuib0oLvgW4TR4rZebrWtDlYDe5MlDwdGtJX3iWu2Rt/gK5HKztFFeo0+6O2kvdZsqmnmXLV14RK+e3upoY+crcSofyqU61ouwnyYLTOqoR5xMUDl4QSCfbkoUngVKxDQr4c5eulnhQqs3WIBM83BVpqSPFnfrdJP3q</xenc:CipherValue>
+ </xenc:CipherData>
+ </xenc:EncryptedKey>
+ </ds:KeyInfo>
+ <xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
+ <xenc:CipherValue>tr9Nhnr8opMNTj5+fWTSfnPhuVm2g3VxF9UPLbub0yrXgEOpIFvR6vf/c2r0g4o1f1ddPmndPPOjqYTln4OT04PT/WLS3lrfoPj4fu+KS3WGfZjL8JmgL/6hkhUHll1tzx4PiBvMVP4MCrH4ieKfHWQDDxVexPznJ3yLbGiplh/jOcot8zgDIEu87x9vQoEM71pDjz2/vBje2DgZN1Bf2K8lRERLWl1dC06EPqH99eUXBVo94LdMqsOEECBJmzfOvivd5JsoQ7x5eZ3cfYmPwtQkQjg8FDLxFpLcXAmadZQrYK9dVIKLRZtI7QxEKV+rd/dHvIvyqRT+YMCobkvSC8xdneVlr0PgXL2oY3yFaGbL4a1paIpDxkEe1sCbz4ucY/SRoKd6zqmBFXIS1wZSkUcrvuIzuGBho7Bn0GPc167kaplLshW/CoklNLQJEFnjWu2VPGLj8IZjApYVkRgv/LZZRLJ8I4zfAI6wblqPQPsLm1adiBtBsI2CygkOkL5T5PPHmjJxFWoczIiNGfxwOUpMSGrQE2GVjsAc3r76FwJW40PjcgEsDeAsZaX0ct7LfJolhZSMI/h9cu2VtDgxq/eeGZzXVvTIG68oKUjLnKlCXCcwE+KdHjLnVF8N0gwWYau59Ln8DODP6l1kvmb7O034uI3eiTumqgJT27uAJ9KQol1LsmHZZoeiDJY4nMV7MAHfIMSHetzPiOSF2xilkwi0te7cWfJRDhWtymIilMTDkJTTqN9EHK5GbZ3JzPVsyw+PbI36PudiS3KOsb6qdb42fcWfOFeeOLOEsb1pxk/aHk8sG14i01MTGGJRhPZcBmrxJmLy5TNZ8Xp/kiA1w4cTwoDk8aQcUeMg350rEGbhW6/9Jm5BPC+z0GhnzWo0DnzLuJCu1zSmO2s+bUwBnGH/ZFxbf4DWCmYrq+T32hfrTFUncZOenlLkPgM7vJK/o4ND/d76z00ud6BoPPa67q4ZxAMgo2T2+HGjrL6JsbivcjOazByKSq9aCOYy9LpaWD20k8c3voqzt+GUJadc7bEeEn7fBI0Y7J4hRfFQiSanXn/fHbUPUZMlctDgkJrQFeRI0Jrkrlp8k8RErMdAdYQI8j5cMphKTXAF/gpc0dFI6HPgVQk7ioEYIUh/44OssVLKjYoQAZnZN1ndgVHHl8jogB3KQ+mVJoBlnckyWneO9bNcnekfWI6F4UHdzzjiPeujobglkzc5eOnw2fL8ELqHW4gzKFfrukQgOCgmEHIJV8TBzGRLmIN3kLvPvA7Q3oneb6J2+FPwT1wZupKoqwmKDiUtu+O99JGsjW6J5C9MdVT5DE0NShM4FU/XvmPAQIOO31Rg1HIdNH9fodCtyA8YT76Xjpi73nt7SjkJyKX/jdHMhFzHTblYpDV98ZoRq8I/AU71KbV1w7u5ThNfPHYBsWVm28KtpzfvxV0yFV5HtTHwLiXmu9P0D2o1K6aB6XC6hlgeB1VtujJBya7zaF45xLGVfYDj4HALqxqDDv0T+qIlgoRe1/c8LbVdYzZU8Yseqe1QC6NQA7277xBheF8LqHTXBaOeIOVgkKHHTb64AZ2eqrnKGnWV3VT1k3GszboZz4TNKg3izu7R54+UmF6psLhVW1mUaHvjVviZiXlu215XlOVop7P3Q6WBR1i8p4PvLSy5IiEwCRIPzXSjVPkFHujwcaqHZ0VgD+p9lfHHh4LARcZM9+tvD67FNt4Uq9W+l3mocN2suGEJfWElm9Z1TdPKzqQUJwZPEnL1JZKykAic5CmTqo7uqGHzIL0SzIrsnkbPclFFgHjXWJOgMfnya58pUh3RX7QQ1+ZH6/C0qeILzXjAJXNKfHEgro99GFGN5kxQShDqJljWKDjbJ9M8ioDqt/4KvMwkferpaNro4/06k8/qhKmFh/I/cNd9SfIaYEU95Ej121nFBD20qOXCUKCQ3rP1z33ezZ2Lld+RSr+fkJ/8IlarVCitENmR6fn7cVCmwEYcK7kfZSCZ0FFgb9gf/LpPE4jlZ3voyNquvXIrlG47WC6IwHOieY4PalONmhKHkYzhngnAyvuHQ/vUJ5PxF/9Ks7KQA+UVFaP/fiuNED8UZ/iziBmEolw2/A==</xenc:CipherValue>
+ </xenc:CipherData>
+ </xenc:EncryptedData>
+ </saml2:EncryptedAssertion>
+</saml2p:Response>
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/AuthRequest_without_sig_missing_id.xml b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/AuthRequest_without_sig_missing_id.xml
new file mode 100644
index 00000000..e028d8d1
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/AuthRequest_without_sig_missing_id.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceIndex="1" AttributeConsumingServiceIndex="0" Destination="https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp2/post" IssueInstant="2014-03-05T06:39:02.775Z" Version="2.0">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://demo.egiz.gv.at/demoportal_demologin/</saml2:Issuer>
+ <saml2:Subject xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
+ <saml2:NameID>https://demo.egiz.gv.at/demoportal_demologin/</saml2:NameID>
+ </saml2:Subject>
+ <saml2p:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/>
+ <saml2p:RequestedAuthnContext>
+ <saml2:AuthnContextClassRef xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://www.stork.gov.eu/1.0/citizenQAALevel/4</saml2:AuthnContextClassRef>
+ </saml2p:RequestedAuthnContext>
+</saml2p:AuthnRequest>
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/Response_without_sig_1.xml b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/Response_without_sig_1.xml
index 2683742e..e6530cca 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/Response_without_sig_1.xml
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/Response_without_sig_1.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://demo.egiz.gv.at/demoportal_demologin/securearea.action" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" ID="_4c1c39ee0969b320bf0cae37816f7d5b" Destination="https://demo.egiz.gv.at/demoportal_demologin/securearea.action" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://demo.egiz.gv.at/demoportal_demologin/</saml2:Issuer>
<saml2p:Status>
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/Response_without_sig_classpath_entityid.xml b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/Response_without_sig_classpath_entityid.xml
new file mode 100644
index 00000000..2683742e
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/Response_without_sig_classpath_entityid.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://demo.egiz.gv.at/demoportal_demologin/securearea.action" InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://demo.egiz.gv.at/demoportal_demologin/</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_602c3236bffaf71ac3ac88674e76ff9f" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0">
+ <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp/metadata</saml2:Issuer>
+ <saml2:Subject>
+ <saml2:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" NameQualifier="urn:publicid:gv.at:cdid+BF">QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:NameID>
+ <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
+ <saml2:SubjectConfirmationData InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" NotOnOrAfter="2014-03-05T06:44:51.017Z" Recipient="https://demo.egiz.gv.at/demoportal_demologin/securearea.action"/>
+ </saml2:SubjectConfirmation>
+ </saml2:Subject>
+ <saml2:Conditions NotBefore="2014-03-05T06:39:51.017Z" NotOnOrAfter="2014-03-05T06:44:51.017Z">
+ <saml2:AudienceRestriction>
+ <saml2:Audience>https://demo.egiz.gv.at/demoportal_demologin/</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://www.stork.gov.eu/1.0/citizenQAALevel/4</saml2:AuthnContextClassRef>
+ </saml2:AuthnContext>
+ </saml2:AuthnStatement>
+ <saml2:AttributeStatement>
+ <saml2:Attribute FriendlyName="PVP-VERSION" Name="urn:oid:1.2.40.0.10.2.1.1.261.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">2.1</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="PRINCIPAL-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.20" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Mustermann</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Max</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="BIRTHDATE" Name="urn:oid:1.2.40.0.10.2.1.1.55" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1940-01-01</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="BPK" Name="urn:oid:1.2.40.0.10.2.1.1.149" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">BF:QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="EID-CITIZEN-QAA-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.94" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:integer">4</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="EID-ISSUING-NATION" Name="urn:oid:1.2.40.0.10.2.1.1.261.32" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">AT</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="EID-SECTOR-FOR-IDENTIFIER" Name="urn:oid:1.2.40.0.10.2.1.1.261.34" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">urn:publicid:gv.at:cdid+BF</saml2:AttributeValue>
+ </saml2:Attribute>
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/eIDAS_connector_authn.xml b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/eIDAS_connector_authn.xml
new file mode 100644
index 00000000..8ca219a7
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/eIDAS_connector_authn.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xs="http://www.w3.org/2001/XMLSchema" AssertionConsumerServiceIndex="0" Destination="https://eidas-test.bmi.gv.at/ms_connector/pvp/post" ID="_d9748baa2c1d4cdaa436b2191307fc0e" IsPassive="false" IssueInstant="2020-02-06T15:18:56.002Z" ProviderName="OpenID Connect Demo" Version="2.0">
+ <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/metadata</saml2:Issuer>
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:SignedInfo>
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <ds:Reference URI="#_d9748baa2c1d4cdaa436b2191307fc0e">
+ <ds:Transforms>
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
+ <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"/>
+ </ds:Transform>
+ </ds:Transforms>
+ <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <ds:DigestValue>LxI6QpEx3gT26uxEJi9xZBSVeZIEPUiFYn48Kn8484E=</ds:DigestValue>
+ </ds:Reference>
+ </ds:SignedInfo>
+ <ds:SignatureValue>Id1Zxcrp5RgQw63/NnsYItW82JIWbBhyhL2l/vvcDNN6ccMo5NMY8qcPfmUuOmzi4JdbolAlR3wvoOu4CTXSl8w6Gz67Bbv4qP2kn+Mn6y2Eo40DMM2eEPq529yu9Aa4vU7uLVCHVUGw6vjvlnBeLw4Axwi2v1uxmGIEORb2XKeoy1DjWI9EdhJf7bufL+fEW3AdzZ5GRAUtZ3zh569G9BNnigzUg+j5Rn7An99QR1+2OrxTCFazH7m+Z8ouFXD9LEFtuJJzSEsRGIrU9/9RVYE6gYlb3qA3At2pY5sso2TEUqY2uknBCybz5PoSChAt+SgMp63nWoc9XRk4j/Lkww==</ds:SignatureValue>
+ <ds:KeyInfo>
+ <ds:X509Data>
+ <ds:X509Certificate>MIIDKzCCAhMCBFrxKO4wDQYJKoZIhvcNAQELBQAwWjELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
+SVoxGDAWBgNVBAsMD2RlbW8uZWdpei5ndi5hdDEiMCAGA1UEAwwZTU9BLUlEIElEUCAoVGVzdC1W
+ZXJzaW9uKTAeFw0xODA1MDgwNDM0NTRaFw0yMTAxMzEwNDM0NTRaMFoxCzAJBgNVBAYTAkFUMQ0w
+CwYDVQQKDARFR0laMRgwFgYDVQQLDA9kZW1vLmVnaXouZ3YuYXQxIjAgBgNVBAMMGU1PQS1JRCBJ
+RFAgKFRlc3QtVmVyc2lvbikwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCaFnqoaYoq
+UptenemC6FiVDg5F2hEjpjix8+ow6/6QhUl2cPOS0uwZHaIvwT/RVbJ9CPdil6+11qaCPfZ+FoY+
+M+ke7TRd2RS1DqFbe1KC0imEnwemyLQrYe5Pm7DNcaY/kHTTq+k0eeGbYH0U/Iopyi0VuN5OWl4F
+Vg45pf7knhXkaimItdjnCXnKcYM91mmltCf6TDgUrz7US7PmgvinnhfBgdITAT4GRr4ehliT+/jt
+1OzHEyWRHanBGIpXNeZNqxgnpnGtaDh4JZuYR8qfH+GRK6dtW2ziej6rGIiUElGVCkXsohgxMNzq
+nWeD9JT8+yyp1XZlyQf+IxhhESQLAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIFejAFQepaEl/kC
+VLvidMR+MXq5LCGHthUiI6eDTQZ+H7lZdHlj547XwEdX15b6Md3h7eSJ4hwlfV4go/0FaoLPzvVq
+itwtYY5htywB3B6ZV34Eyi6C59Gl34XrV8CWxH4KKwLsVAjAy+/p/Xh0q2pzSBkeOChzBMBkjmyc
+2Ue4MEKdL9guzp6+Yc/HL/phHAKYapkVyFwvsdqWOgyRzxAHINko8ExImMMB3xB5a52kfqLcui5O
+fzEhjwLFJaGBMmFCmFGGOUwtIvl/6ZQ2LLzOE9+giVK9WsIgH11Pu+ejPFAbXf8cf4oWhbAfTkiy
+4jpXrp77JXFRSDWddb0yePc=</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </ds:Signature>
+ <saml2p:Extensions>
+ <eid:RequestedAttributes xmlns:eid="http://eid.gv.at/eID/attributes/saml-extensions">
+ <eid:RequestedAttribute FriendlyName="EID-SECTOR-FOR-IDENTIFIER" Name="urn:oid:1.2.40.0.10.2.1.1.261.34" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true">
+ <eid:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">urn:publicid:gv.at:cdid+BF</eid:AttributeValue>
+ </eid:RequestedAttribute>
+ </eid:RequestedAttributes>
+ </saml2p:Extensions>
+ <saml2p:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/>
+ <saml2p:RequestedAuthnContext Comparison="minimum">
+ <saml2:AuthnContextClassRef xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://eidas.europa.eu/LoA/low</saml2:AuthnContextClassRef>
+ </saml2p:RequestedAuthnContext>
+ <saml2p:Scoping>
+ <saml2p:RequesterID>https://demo.egiz.gv.at/demoportal-openID_demo</saml2p:RequesterID>
+ </saml2p:Scoping>
+</saml2p:AuthnRequest> \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_junit_keystore.xml b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_junit_keystore.xml
index 96560960..7fdbef90 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_junit_keystore.xml
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_junit_keystore.xml
@@ -71,21 +71,22 @@ ANsmjI2azWiTSFjb7Ou5fnCfbeiJUP0s66m8qS4rYl9L
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
- <ds:X509Certificate>MIIDKzCCAhMCBFrxKO4wDQYJKoZIhvcNAQELBQAwWjELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
-SVoxGDAWBgNVBAsMD2RlbW8uZWdpei5ndi5hdDEiMCAGA1UEAwwZTU9BLUlEIElEUCAoVGVzdC1W
-ZXJzaW9uKTAeFw0xODA1MDgwNDM0NTRaFw0yMTAxMzEwNDM0NTRaMFoxCzAJBgNVBAYTAkFUMQ0w
-CwYDVQQKDARFR0laMRgwFgYDVQQLDA9kZW1vLmVnaXouZ3YuYXQxIjAgBgNVBAMMGU1PQS1JRCBJ
-RFAgKFRlc3QtVmVyc2lvbikwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCaFnqoaYoq
-UptenemC6FiVDg5F2hEjpjix8+ow6/6QhUl2cPOS0uwZHaIvwT/RVbJ9CPdil6+11qaCPfZ+FoY+
-M+ke7TRd2RS1DqFbe1KC0imEnwemyLQrYe5Pm7DNcaY/kHTTq+k0eeGbYH0U/Iopyi0VuN5OWl4F
-Vg45pf7knhXkaimItdjnCXnKcYM91mmltCf6TDgUrz7US7PmgvinnhfBgdITAT4GRr4ehliT+/jt
-1OzHEyWRHanBGIpXNeZNqxgnpnGtaDh4JZuYR8qfH+GRK6dtW2ziej6rGIiUElGVCkXsohgxMNzq
-nWeD9JT8+yyp1XZlyQf+IxhhESQLAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIFejAFQepaEl/kC
-VLvidMR+MXq5LCGHthUiI6eDTQZ+H7lZdHlj547XwEdX15b6Md3h7eSJ4hwlfV4go/0FaoLPzvVq
-itwtYY5htywB3B6ZV34Eyi6C59Gl34XrV8CWxH4KKwLsVAjAy+/p/Xh0q2pzSBkeOChzBMBkjmyc
-2Ue4MEKdL9guzp6+Yc/HL/phHAKYapkVyFwvsdqWOgyRzxAHINko8ExImMMB3xB5a52kfqLcui5O
-fzEhjwLFJaGBMmFCmFGGOUwtIvl/6ZQ2LLzOE9+giVK9WsIgH11Pu+ejPFAbXf8cf4oWhbAfTkiy
-4jpXrp77JXFRSDWddb0yePc=</ds:X509Certificate>
+ <ds:X509Certificate>MIIC+jCCAeKgAwIBAgIEXjF+fTANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJB
+VDENMAsGA1UEBwwERUdJWjEOMAwGA1UECgwFalVuaXQxETAPBgNVBAMMCE1ldGFk
+YXRhMB4XDTIwMDEyOTEyNDU0OVoXDTI2MDEyODEyNDU0OVowPzELMAkGA1UEBhMC
+QVQxDTALBgNVBAcMBEVHSVoxDjAMBgNVBAoMBWpVbml0MREwDwYDVQQDDAhNZXRh
+ZGF0YTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK230G3dxNbNlSYA
+O5Kx/Js0aBAgxMt7q9m+dA35fK/dOvF/GjrqjWsMCnax+no9gLnq6x0gXiJclz6H
+rp/YDOfLrJjMpNL/r0FWT947vbnEj7eT8TdY5d6Yi8AZulZmjiCI5nbZh2zwrP4+
+WqRroLoPhXQj8mDyp26M4xHBBUhLMRc2HV4S+XH4uNZ/vTmb8vBg31XGHCY33gl7
+/KA54JNGxJdN8Dxv6yHYsm91ZfVrX39W0iYLUNhUCkolwuQmjDVfrExM8BTLIONb
+f+erJoCm3A9ghZyDYRQ/e69/UEUqDa6XOzykr88INkQscEiAXCDS+EBPMpKo+t3l
+PIA9r7kCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAh/2mg4S03bdZy1OVtEAudBT9
+YZb9OF34hxPtNbkB/V04wSIg1d4TBr5KDhV7CdiUOxPZzHpS8LUCgfGX306FB6NX
+zh/b67uTOPaE72AB4VIT/Np0fsM7k5WhG9k9NoprIGiqCz2lXcfpZiT+LtSO1vWS
+YI87wR9KOSWjcw/5i5qZIAJuwvLCQj5JtUsmrhHK75222J3TJf4dS/gfN4xfY2rW
+9vcXtH6//8WdWp/zx9V7Z1ZsDb8TDKtBCEGuFDgVeU5ScKtVq8qRoUKD3Ve76cZi
+purO3KrRrVAuZP2EfLkZdHEHqe8GPigNnZ5kTn8V2VJ3iRAQ73hpJRR98tFd0A==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_junit_keystore_classpath_entityId.xml b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_junit_keystore_classpath_entityId.xml
new file mode 100644
index 00000000..cfc334a6
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_junit_keystore_classpath_entityId.xml
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_2e23ca9b2ba4dc9eef15187830d07ff0" entityID="classpath:/data/pvp_metadata_junit_keystore_classpath_entityId.xml" validUntil="2045-02-05T06:41:42.966Z">
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:SignedInfo>
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <ds:Reference URI="#_2e23ca9b2ba4dc9eef15187830d07ff0">
+ <ds:Transforms>
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ </ds:Transforms>
+ <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <ds:DigestValue>Jy/c0ZvVJSfWzSoAcxDx/o+T5W61vvNJNqTFz2o+ILc=</ds:DigestValue>
+ </ds:Reference>
+ </ds:SignedInfo>
+ <ds:SignatureValue>chMxIdwrPvr78j3oTtgS7udbydy9kye1bbeQ4jm2GeFKUfxvJqY+vt9MjVnWFeR4c16gd80BjZJ6xxD5i5Ifci3YtxeKSxq0ttH/xZYEhJZkD/0NrGUhSvNV9zuLAz3uGk/LJ+2JxRq7dbnW4n9MtGuYhea8OW9/Pr1xI1KyskQS76NZDsGjjfnFWbFXahLoQZULU4Ke3SfZVqLATTn0J34RZnjNH3QieY3LhRzOVu/I5yeZtnLgUS6dg0Gab9DA/pdNFaC632iaE5QCXJmhgpqkjbkayO9e8N93YGFjbszhU1Kws5OUGjXjfCZwezLeOUZoKEfo5c+4+zEaTrEQjg==</ds:SignatureValue>
+ <ds:KeyInfo>
+ <ds:X509Data>
+ <ds:X509Certificate>MIIDKzCCAhMCBFrxKO4wDQYJKoZIhvcNAQELBQAwWjELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
+SVoxGDAWBgNVBAsMD2RlbW8uZWdpei5ndi5hdDEiMCAGA1UEAwwZTU9BLUlEIElEUCAoVGVzdC1W
+ZXJzaW9uKTAeFw0xODA1MDgwNDM0NTRaFw0yMTAxMzEwNDM0NTRaMFoxCzAJBgNVBAYTAkFUMQ0w
+CwYDVQQKDARFR0laMRgwFgYDVQQLDA9kZW1vLmVnaXouZ3YuYXQxIjAgBgNVBAMMGU1PQS1JRCBJ
+RFAgKFRlc3QtVmVyc2lvbikwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCaFnqoaYoq
+UptenemC6FiVDg5F2hEjpjix8+ow6/6QhUl2cPOS0uwZHaIvwT/RVbJ9CPdil6+11qaCPfZ+FoY+
+M+ke7TRd2RS1DqFbe1KC0imEnwemyLQrYe5Pm7DNcaY/kHTTq+k0eeGbYH0U/Iopyi0VuN5OWl4F
+Vg45pf7knhXkaimItdjnCXnKcYM91mmltCf6TDgUrz7US7PmgvinnhfBgdITAT4GRr4ehliT+/jt
+1OzHEyWRHanBGIpXNeZNqxgnpnGtaDh4JZuYR8qfH+GRK6dtW2ziej6rGIiUElGVCkXsohgxMNzq
+nWeD9JT8+yyp1XZlyQf+IxhhESQLAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIFejAFQepaEl/kC
+VLvidMR+MXq5LCGHthUiI6eDTQZ+H7lZdHlj547XwEdX15b6Md3h7eSJ4hwlfV4go/0FaoLPzvVq
+itwtYY5htywB3B6ZV34Eyi6C59Gl34XrV8CWxH4KKwLsVAjAy+/p/Xh0q2pzSBkeOChzBMBkjmyc
+2Ue4MEKdL9guzp6+Yc/HL/phHAKYapkVyFwvsdqWOgyRzxAHINko8ExImMMB3xB5a52kfqLcui5O
+fzEhjwLFJaGBMmFCmFGGOUwtIvl/6ZQ2LLzOE9+giVK9WsIgH11Pu+ejPFAbXf8cf4oWhbAfTkiy
+4jpXrp77JXFRSDWddb0yePc=</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </ds:Signature>
+ <md:IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+ <md:KeyDescriptor use="signing">
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate>MIIC+jCCAeKgAwIBAgIEXjF+fTANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJB
+VDENMAsGA1UEBwwERUdJWjEOMAwGA1UECgwFalVuaXQxETAPBgNVBAMMCE1ldGFk
+YXRhMB4XDTIwMDEyOTEyNDU0OVoXDTI2MDEyODEyNDU0OVowPzELMAkGA1UEBhMC
+QVQxDTALBgNVBAcMBEVHSVoxDjAMBgNVBAoMBWpVbml0MREwDwYDVQQDDAhNZXRh
+ZGF0YTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK230G3dxNbNlSYA
+O5Kx/Js0aBAgxMt7q9m+dA35fK/dOvF/GjrqjWsMCnax+no9gLnq6x0gXiJclz6H
+rp/YDOfLrJjMpNL/r0FWT947vbnEj7eT8TdY5d6Yi8AZulZmjiCI5nbZh2zwrP4+
+WqRroLoPhXQj8mDyp26M4xHBBUhLMRc2HV4S+XH4uNZ/vTmb8vBg31XGHCY33gl7
+/KA54JNGxJdN8Dxv6yHYsm91ZfVrX39W0iYLUNhUCkolwuQmjDVfrExM8BTLIONb
+f+erJoCm3A9ghZyDYRQ/e69/UEUqDa6XOzykr88INkQscEiAXCDS+EBPMpKo+t3l
+PIA9r7kCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAh/2mg4S03bdZy1OVtEAudBT9
+YZb9OF34hxPtNbkB/V04wSIg1d4TBr5KDhV7CdiUOxPZzHpS8LUCgfGX306FB6NX
+zh/b67uTOPaE72AB4VIT/Np0fsM7k5WhG9k9NoprIGiqCz2lXcfpZiT+LtSO1vWS
+YI87wR9KOSWjcw/5i5qZIAJuwvLCQj5JtUsmrhHK75222J3TJf4dS/gfN4xfY2rW
+9vcXtH6//8WdWp/zx9V7Z1ZsDb8TDKtBCEGuFDgVeU5ScKtVq8qRoUKD3Ve76cZi
+purO3KrRrVAuZP2EfLkZdHEHqe8GPigNnZ5kTn8V2VJ3iRAQ73hpJRR98tFd0A==</ds:X509Certificate>
+ </ds:X509Data>
+ <ds:X509Data>
+ <ds:X509Certificate>MIIBbTCCARKgAwIBAgIEXjF+qTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJBVDEN
+MAsGA1UEBwwERUdJWjEOMAwGA1UECgwFalVuaXQxEDAOBgNVBAMMB3NpZ25pbmcw
+HhcNMjAwMTI5MTI0NjMzWhcNMjcwMTI4MTI0NjMzWjA+MQswCQYDVQQGEwJBVDEN
+MAsGA1UEBwwERUdJWjEOMAwGA1UECgwFalVuaXQxEDAOBgNVBAMMB3NpZ25pbmcw
+WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASRt7gZRrr4rSEE7Q922oKQJF+mlkwC
+LZnv8ZzHtH54s4VdyQFIBjQF1PPf9PTn+5tid8QJehZPndcoeD7J8fPJMAoGCCqG
+SM49BAMCA0kAMEYCIQDFUO0owvqMVRO2FmD+vb8mqJBpWCE6Cl5pEHaygTa5LwIh
+ANsmjI2azWiTSFjb7Ou5fnCfbeiJUP0s66m8qS4rYl9L
+ </ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp2/post"/>
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp2/redirect"/>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
+ <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp2/post"/>
+ <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp2/redirect"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATOR-NATURAL-PERSON-BIRTHDATE" Name="urn:oid:1.2.40.0.10.2.1.1.261.82" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="BPK" Name="urn:oid:1.2.40.0.10.2.1.1.149" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATOR-NATURAL-PERSON-FAMILY-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.80" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-CCS-URL" Name="urn:oid:1.2.40.0.10.2.1.1.261.64" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATE-PROF-REP-OID" Name="urn:oid:1.2.40.0.10.2.1.1.261.86" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="BIRTHDATE" Name="urn:oid:1.2.40.0.10.2.1.1.55" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="PRINCIPAL-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.20" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-AUTH-BLOCK" Name="urn:oid:1.2.40.0.10.2.1.1.261.62" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATOR-LEGAL-PERSON-FULL-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.84" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATE-TYPE" Name="urn:oid:1.2.40.0.10.2.1.1.261.68" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SIGNER-CERTIFICATE" Name="urn:oid:1.2.40.0.10.2.1.1.261.66" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="ENC-BPK-LIST" Name="urn:oid:1.2.40.0.10.2.1.1.261.22" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATE-PROF-REP-DESCRIPTION" Name="urn:oid:1.2.40.0.10.2.1.1.261.88" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="BPK-LIST" Name="urn:oid:1.2.40.0.10.2.1.1.261.28" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATE-REFERENCE-VALUE" Name="urn:oid:1.2.40.0.10.2.1.1.261.90" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-CITIZEN-QAA-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.94" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATOR-NATURAL-PERSON-ENC-BPK-LIST" Name="urn:oid:1.2.40.0.10.2.1.1.261.72" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATE-FULL-MANDATE" Name="urn:oid:1.2.40.0.10.2.1.1.261.92" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATOR-NATURAL-PERSON-SOURCE-PIN" Name="urn:oid:1.2.40.0.10.2.1.1.261.70" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATOR-LEGAL-PERSON-SOURCE-PIN-TYPE" Name="urn:oid:1.2.40.0.10.2.1.1.261.76" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATOR-NATURAL-PERSON-BPK" Name="urn:oid:1.2.40.0.10.2.1.1.261.98" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-ISSUING-NATION" Name="urn:oid:1.2.40.0.10.2.1.1.261.32" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="PVP-VERSION" Name="urn:oid:1.2.40.0.10.2.1.1.261.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATOR-NATURAL-PERSON-BPK-LIST" Name="urn:oid:1.2.40.0.10.2.1.1.261.73" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-STORK-TOKEN" Name="urn:oid:1.2.40.0.10.2.1.1.261.96" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATOR-LEGAL-PERSON-SOURCE-PIN" Name="urn:oid:1.2.40.0.10.2.1.1.261.100" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SOURCE-PIN" Name="urn:oid:1.2.40.0.10.2.1.1.261.36" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATOR-NATURAL-PERSON-SOURCE-PIN-TYPE" Name="urn:oid:1.2.40.0.10.2.1.1.261.102" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATOR-NATURAL-PERSON-GIVEN-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.78" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SECTOR-FOR-IDENTIFIER" Name="urn:oid:1.2.40.0.10.2.1.1.261.34" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-SOURCE-PIN-TYPE" Name="urn:oid:1.2.40.0.10.2.1.1.261.104" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-E-ID-TOKEN" Name="urn:oid:1.2.40.0.10.2.1.1.261.39" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="MANDATE-TYPE-OID" Name="urn:oid:1.2.40.0.10.2.1.1.261.106" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-IDENTITY-LINK" Name="urn:oid:1.2.40.0.10.2.1.1.261.38" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-CITIZEN-QAA-EIDAS-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.108" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <saml2:Attribute xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" FriendlyName="EID-IDENTITY-STATUS-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.109" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ </md:IDPSSODescriptor>
+ <md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+ <md:KeyDescriptor use="signing">
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate>MIIC+jCCAeKgAwIBAgIEXjF+fTANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJB
+VDENMAsGA1UEBwwERUdJWjEOMAwGA1UECgwFalVuaXQxETAPBgNVBAMMCE1ldGFk
+YXRhMB4XDTIwMDEyOTEyNDU0OVoXDTI2MDEyODEyNDU0OVowPzELMAkGA1UEBhMC
+QVQxDTALBgNVBAcMBEVHSVoxDjAMBgNVBAoMBWpVbml0MREwDwYDVQQDDAhNZXRh
+ZGF0YTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK230G3dxNbNlSYA
+O5Kx/Js0aBAgxMt7q9m+dA35fK/dOvF/GjrqjWsMCnax+no9gLnq6x0gXiJclz6H
+rp/YDOfLrJjMpNL/r0FWT947vbnEj7eT8TdY5d6Yi8AZulZmjiCI5nbZh2zwrP4+
+WqRroLoPhXQj8mDyp26M4xHBBUhLMRc2HV4S+XH4uNZ/vTmb8vBg31XGHCY33gl7
+/KA54JNGxJdN8Dxv6yHYsm91ZfVrX39W0iYLUNhUCkolwuQmjDVfrExM8BTLIONb
+f+erJoCm3A9ghZyDYRQ/e69/UEUqDa6XOzykr88INkQscEiAXCDS+EBPMpKo+t3l
+PIA9r7kCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAh/2mg4S03bdZy1OVtEAudBT9
+YZb9OF34hxPtNbkB/V04wSIg1d4TBr5KDhV7CdiUOxPZzHpS8LUCgfGX306FB6NX
+zh/b67uTOPaE72AB4VIT/Np0fsM7k5WhG9k9NoprIGiqCz2lXcfpZiT+LtSO1vWS
+YI87wR9KOSWjcw/5i5qZIAJuwvLCQj5JtUsmrhHK75222J3TJf4dS/gfN4xfY2rW
+9vcXtH6//8WdWp/zx9V7Z1ZsDb8TDKtBCEGuFDgVeU5ScKtVq8qRoUKD3Ve76cZi
+purO3KrRrVAuZP2EfLkZdHEHqe8GPigNnZ5kTn8V2VJ3iRAQ73hpJRR98tFd0A==</ds:X509Certificate>
+ </ds:X509Data>
+ <ds:X509Data>
+ <ds:X509Certificate>MIIBbTCCARKgAwIBAgIEXjF+qTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJBVDEN
+MAsGA1UEBwwERUdJWjEOMAwGA1UECgwFalVuaXQxEDAOBgNVBAMMB3NpZ25pbmcw
+HhcNMjAwMTI5MTI0NjMzWhcNMjcwMTI4MTI0NjMzWjA+MQswCQYDVQQGEwJBVDEN
+MAsGA1UEBwwERUdJWjEOMAwGA1UECgwFalVuaXQxEDAOBgNVBAMMB3NpZ25pbmcw
+WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASRt7gZRrr4rSEE7Q922oKQJF+mlkwC
+LZnv8ZzHtH54s4VdyQFIBjQF1PPf9PTn+5tid8QJehZPndcoeD7J8fPJMAoGCCqG
+SM49BAMCA0kAMEYCIQDFUO0owvqMVRO2FmD+vb8mqJBpWCE6Cl5pEHaygTa5LwIh
+ANsmjI2azWiTSFjb7Ou5fnCfbeiJUP0s66m8qS4rYl9L
+ </ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:KeyDescriptor use="encryption">
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate>MIIDKzCCAhMCBFrxKO4wDQYJKoZIhvcNAQELBQAwWjELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
+SVoxGDAWBgNVBAsMD2RlbW8uZWdpei5ndi5hdDEiMCAGA1UEAwwZTU9BLUlEIElEUCAoVGVzdC1W
+ZXJzaW9uKTAeFw0xODA1MDgwNDM0NTRaFw0yMTAxMzEwNDM0NTRaMFoxCzAJBgNVBAYTAkFUMQ0w
+CwYDVQQKDARFR0laMRgwFgYDVQQLDA9kZW1vLmVnaXouZ3YuYXQxIjAgBgNVBAMMGU1PQS1JRCBJ
+RFAgKFRlc3QtVmVyc2lvbikwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCaFnqoaYoq
+UptenemC6FiVDg5F2hEjpjix8+ow6/6QhUl2cPOS0uwZHaIvwT/RVbJ9CPdil6+11qaCPfZ+FoY+
+M+ke7TRd2RS1DqFbe1KC0imEnwemyLQrYe5Pm7DNcaY/kHTTq+k0eeGbYH0U/Iopyi0VuN5OWl4F
+Vg45pf7knhXkaimItdjnCXnKcYM91mmltCf6TDgUrz7US7PmgvinnhfBgdITAT4GRr4ehliT+/jt
+1OzHEyWRHanBGIpXNeZNqxgnpnGtaDh4JZuYR8qfH+GRK6dtW2ziej6rGIiUElGVCkXsohgxMNzq
+nWeD9JT8+yyp1XZlyQf+IxhhESQLAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIFejAFQepaEl/kC
+VLvidMR+MXq5LCGHthUiI6eDTQZ+H7lZdHlj547XwEdX15b6Md3h7eSJ4hwlfV4go/0FaoLPzvVq
+itwtYY5htywB3B6ZV34Eyi6C59Gl34XrV8CWxH4KKwLsVAjAy+/p/Xh0q2pzSBkeOChzBMBkjmyc
+2Ue4MEKdL9guzp6+Yc/HL/phHAKYapkVyFwvsdqWOgyRzxAHINko8ExImMMB3xB5a52kfqLcui5O
+fzEhjwLFJaGBMmFCmFGGOUwtIvl/6ZQ2LLzOE9+giVK9WsIgH11Pu+ejPFAbXf8cf4oWhbAfTkiy
+4jpXrp77JXFRSDWddb0yePc=</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/post" index="0" isDefault="true"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/redirect" index="1"/>
+ <md:AttributeConsumingService index="0" isDefault="true">
+ <md:ServiceName xml:lang="en">Default Service</md:ServiceName>
+ <md:RequestedAttribute FriendlyName="BPK" Name="urn:oid:1.2.40.0.10.2.1.1.149" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="PRINCIPAL-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.20" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="BIRTHDATE" Name="urn:oid:1.2.40.0.10.2.1.1.55" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="PVP-VERSION" Name="urn:oid:1.2.40.0.10.2.1.1.261.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="EID-ISSUING-NATION" Name="urn:oid:1.2.40.0.10.2.1.1.261.32" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="MANDATOR-LEGAL-PERSON-SOURCE-PIN-TYPE" Name="urn:oid:1.2.40.0.10.2.1.1.261.76" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
+ <md:RequestedAttribute FriendlyName="MANDATOR-LEGAL-PERSON-FULL-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.84" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
+ <md:RequestedAttribute FriendlyName="MANDATE-TYPE" Name="urn:oid:1.2.40.0.10.2.1.1.261.68" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
+ <md:RequestedAttribute FriendlyName="MANDATOR-LEGAL-PERSON-SOURCE-PIN" Name="urn:oid:1.2.40.0.10.2.1.1.261.100" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
+ <md:RequestedAttribute FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="EID-SECTOR-FOR-IDENTIFIER" Name="urn:oid:1.2.40.0.10.2.1.1.261.34" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ <md:RequestedAttribute FriendlyName="MANDATE-TYPE-OID" Name="urn:oid:1.2.40.0.10.2.1.1.261.106" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
+ <md:RequestedAttribute FriendlyName="EID-IDENTITY-LINK" Name="urn:oid:1.2.40.0.10.2.1.1.261.38" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
+ <md:RequestedAttribute FriendlyName="EID-CITIZEN-QAA-EIDAS-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.108" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
+ </md:AttributeConsumingService>
+ </md:SPSSODescriptor>
+ <md:Organization>
+ <md:OrganizationName xml:lang="de">EGIZ</md:OrganizationName>
+ <md:OrganizationDisplayName xml:lang="de">E-Government Innovationszentrum</md:OrganizationDisplayName>
+ <md:OrganizationURL xml:lang="de">http://www.egiz.gv.at</md:OrganizationURL>
+ </md:Organization>
+ <md:ContactPerson contactType="technical">
+ <md:Company>E-Government Innovationszentrum</md:Company>
+ <md:GivenName>Lenz</md:GivenName>
+ <md:SurName>Thomas</md:SurName>
+ <md:EmailAddress>thomas.lenz@egiz.gv.at</md:EmailAddress>
+ <md:TelephoneNumber>+43 316 873 5525</md:TelephoneNumber>
+ </md:ContactPerson>
+</md:EntityDescriptor>
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_valid_with_entityCategory_egov.xml b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_valid_with_entityCategory_egov.xml
index cb680e82..5129c494 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_valid_with_entityCategory_egov.xml
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/data/pvp_metadata_valid_with_entityCategory_egov.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_ee52efc823faa4334d93d1a787fb2c24" entityID="https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eid/metadata" validUntil="2020-02-05T10:58:10.849Z">
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_ee52efc823faa4334d93d1a787fb2c24" entityID="https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eid/metadata" validUntil="2045-02-05T10:58:10.849Z">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_map_config.beans.xml b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_map_config.beans.xml
index 3e1df7d2..c1660a70 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_map_config.beans.xml
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_map_config.beans.xml
@@ -10,7 +10,9 @@
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
- <bean id="dummyAuthConfig"
- class="at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfig" />
+ <bean id="dummyAuthConfigMap"
+ class="at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfigMap">
+ <constructor-arg value="/config/config_1.props" />
+ </bean>
</beans> \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_spring_config.beans.xml b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_spring_config.beans.xml
index 5aef9544..5319236b 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_spring_config.beans.xml
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_core_spring_config.beans.xml
@@ -10,10 +10,9 @@
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
- <bean id="dummyAuthConfigMap"
- class="at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfigMap">
- <constructor-arg value="/config/config_1.props" />
- </bean>
+ <bean id="dummyAuthConfig"
+ class="at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfig" />
+
<bean id="eaafKeyStoreFactory"
class="at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory" />
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_pvp.beans.xml b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_pvp.beans.xml
index aac94041..e7cc42ed 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_pvp.beans.xml
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/test/resources/spring/test_eaaf_pvp.beans.xml
@@ -16,5 +16,10 @@
<bean id="dummyCredentialProvider"
class="at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider" />
+ <bean id="dummyChainingMetadataResolver"
+ class="at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyMetadataProvider"/>
+
+ <bean id="samlVerificationEngine"
+ class="at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine"/>
</beans> \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/pom.xml b/eaaf_modules/eaaf_module_pvp2_idp/pom.xml
index 2e9cb88d..0170febf 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/pom.xml
+++ b/eaaf_modules/eaaf_module_pvp2_idp/pom.xml
@@ -39,6 +39,12 @@
</dependency>
<dependency>
<groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf_core_utils</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
<artifactId>eaaf-core</artifactId>
<scope>test</scope>
<type>test-jar</type>
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java
index 16cd27cd..f9d7767f 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AuthenticationAction.java
@@ -23,6 +23,19 @@ import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.joda.time.DateTime;
+import org.opensaml.saml.common.xml.SAMLConstants;
+import org.opensaml.saml.saml2.core.Assertion;
+import org.opensaml.saml.saml2.core.AuthnRequest;
+import org.opensaml.saml.saml2.core.Response;
+import org.opensaml.saml.saml2.metadata.AssertionConsumerService;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Service;
+
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.idp.IAction;
import at.gv.egiz.eaaf.core.api.idp.IAuthData;
@@ -44,19 +57,6 @@ import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding;
import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileRequest;
import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
-import org.joda.time.DateTime;
-import org.opensaml.saml.common.xml.SAMLConstants;
-import org.opensaml.saml.saml2.core.Assertion;
-import org.opensaml.saml.saml2.core.AuthnRequest;
-import org.opensaml.saml.saml2.core.Response;
-import org.opensaml.saml.saml2.metadata.AssertionConsumerService;
-import org.opensaml.saml.saml2.metadata.EntityDescriptor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
-import org.springframework.stereotype.Service;
-
@Service("PVPAuthenticationRequestAction")
public class AuthenticationAction implements IAction {
private static final Logger log = LoggerFactory.getLogger(AuthenticationAction.class);
@@ -117,10 +117,10 @@ public class AuthenticationAction implements IAction {
IEncoder binding = null;
if (consumerService.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
- binding = springContext.getBean("PVPRedirectBinding", RedirectBinding.class);
+ binding = springContext.getBean("PvpRedirectBinding", RedirectBinding.class);
} else if (consumerService.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
- binding = springContext.getBean("PVPPOSTBinding", PostBinding.class);
+ binding = springContext.getBean("PvpPostBinding", PostBinding.class);
}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java
index 565f28fb..482a2a09 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/AuthResponseBuilder.java
@@ -31,6 +31,10 @@ import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
import org.joda.time.DateTime;
import org.opensaml.core.criterion.EntityIdCriterion;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.core.xml.io.MarshallingException;
+import org.opensaml.core.xml.io.UnmarshallingException;
+import org.opensaml.core.xml.util.XMLObjectSupport;
import org.opensaml.saml.common.xml.SAMLConstants;
import org.opensaml.saml.criterion.EntityRoleCriterion;
import org.opensaml.saml.criterion.ProtocolCriterion;
@@ -61,6 +65,7 @@ import org.opensaml.xmlsec.keyinfo.impl.provider.InlineX509DataProvider;
import org.opensaml.xmlsec.keyinfo.impl.provider.RSAKeyValueProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
@@ -158,9 +163,14 @@ public class AuthResponseBuilder {
final Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList);
samlEncrypter.setKeyPlacement(KeyPlacement.PEER);
- return samlEncrypter.encrypt(assertion);
+ final Element assertionElement = XMLObjectProviderRegistrySupport.getMarshallerFactory()
+ .getMarshaller(assertion).marshall(assertion);
+ assertionElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xs", "http://www.w3.org/2001/XMLSchema");
- } catch (final EncryptionException | SamlSigningException e1) {
+ return samlEncrypter.encrypt((Assertion)
+ XMLObjectSupport.getUnmarshaller(assertionElement).unmarshall(assertionElement));
+
+ } catch (final EncryptionException | SamlSigningException | MarshallingException | UnmarshallingException e1) {
log.warn("Can not encrypt the PVP2 assertion", e1);
throw new InvalidAssertionEncryptionException();
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthenticationActionTest.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthenticationActionTest.java
new file mode 100644
index 00000000..a88fa869
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthenticationActionTest.java
@@ -0,0 +1,226 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test;
+
+import java.util.Date;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfig;
+import at.gv.egiz.eaaf.modules.pvp2.idp.exception.ResponderErrorException;
+import at.gv.egiz.eaaf.modules.pvp2.idp.impl.AuthenticationAction;
+import at.gv.egiz.eaaf.modules.pvp2.idp.impl.PvpSProfilePendingRequest;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration({"/spring/test_eaaf_pvp.beans.xml"})
+@TestPropertySource(
+ locations = {"/config/config_1.props"})
+public class AuthenticationActionTest {
+
+ @Autowired private DummyAuthConfig authConfig;
+ @Autowired private PvpMetadataResolverFactory metadataResolverFactory;
+ @Autowired private AuthenticationAction action;
+
+ protected MockHttpServletRequest httpReq;
+ protected MockHttpServletResponse httpResp;
+ private PvpSProfilePendingRequest pendingReq;
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void classInitializer() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ }
+
+ /**
+ * Test initializer.
+ *
+ */
+ @Before
+ public void initialize() {
+ httpReq = new MockHttpServletRequest();
+ httpResp = new MockHttpServletResponse();
+
+ pendingReq = new PvpSProfilePendingRequest();
+
+ }
+
+ @Test
+ public void checkNeedAuthFlag() {
+ Assert.assertTrue("Wrong 'needAuth' flag", action.needAuthentication(pendingReq, httpReq, httpResp));
+
+ }
+
+ @Test
+ public void noAuthnRequestInPendingRequest() {
+
+ IAuthData authData = generateAuthData();
+
+ try {
+ action.processRequest(pendingReq, httpReq, httpResp, authData);
+ Assert.fail("No SAML requst not detected");
+
+ } catch (ResponderErrorException e) {
+ Assert.assertEquals("Wrong errorCode", "pvp2.01", e.getErrorId());
+ }
+
+ }
+
+ private IAuthData generateAuthData() {
+ return new IAuthData() {
+
+ @Override
+ public boolean isSsoSession() {
+ return false;
+ }
+
+ @Override
+ public boolean isForeigner() {
+ return false;
+ }
+
+ @Override
+ public boolean isBaseIdTransferRestrication() {
+ return true;
+ }
+
+ @Override
+ public Date getSsoSessionValidTo() {
+ return null;
+
+ }
+
+ @Override
+ public String getSessionIndex() {
+ return null;
+
+ }
+
+ @Override
+ public String getNameIdFormat() {
+ return null;
+
+ }
+
+ @Override
+ public String getNameID() {
+ return null;
+
+ }
+
+ @Override
+ public IIdentityLink getIdentityLink() {
+ return null;
+
+ }
+
+ @Override
+ public String getIdentificationValue() {
+ return null;
+
+ }
+
+ @Override
+ public String getIdentificationType() {
+ return null;
+
+ }
+
+ @Override
+ public String getGivenName() {
+ return RandomStringUtils.randomAlphabetic(10);
+
+ }
+
+ @Override
+ public <T> T getGenericData(String key, Class<T> clazz) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getFormatedDateOfBirth() {
+ return DateFormatUtils.format(getDateOfBirth(), "yyyy-MM-dd");
+ }
+
+ @Override
+ public String getFamilyName() {
+ return RandomStringUtils.randomAlphabetic(10);
+
+ }
+
+ @Override
+ public String getEncryptedSourceIdType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getEncryptedSourceId() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getEidasQaaLevel() {
+ return EaafConstants.EIDAS_LOA_LOW;
+ }
+
+ @Override
+ public Date getDateOfBirth() {
+ return new Date();
+
+ }
+
+ @Override
+ public String getCiticenCountryCode() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getBpkType() {
+ return EaafConstants.URN_PREFIX_CDID + RandomStringUtils.randomAlphabetic(2);
+ }
+
+ @Override
+ public String getBpk() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public String getAuthenticationIssuer() {
+ return RandomStringUtils.randomAlphabetic(10);
+ }
+
+ @Override
+ public String getAuthenticationIssueInstantString() {
+ return DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT.format(getAuthenticationIssueInstant());
+ }
+
+ @Override
+ public Date getAuthenticationIssueInstant() {
+ return new Date();
+ }
+ };
+
+ }
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthnResponseBuilderTest.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthnResponseBuilderTest.java
index 98cf5f40..b2e528c4 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthnResponseBuilderTest.java
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/AuthnResponseBuilderTest.java
@@ -7,12 +7,16 @@ import javax.xml.transform.TransformerException;
import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfig;
import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SamlAssertionValidationExeption;
import at.gv.egiz.eaaf.modules.pvp2.idp.exception.InvalidAssertionEncryptionException;
import at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.AuthResponseBuilder;
import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine;
import at.gv.egiz.eaaf.modules.pvp2.test.binding.PostBindingTest;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
import org.apache.commons.lang3.RandomStringUtils;
import org.joda.time.DateTime;
@@ -43,6 +47,8 @@ public class AuthnResponseBuilderTest {
@Autowired private DummyAuthConfig authConfig;
@Autowired private PvpMetadataResolverFactory metadataResolverFactory;
+ @Autowired private SamlVerificationEngine verifyEngine;
+ @Autowired private DummyCredentialProvider credentialProvider;
/**
* JUnit class initializer.
@@ -99,4 +105,52 @@ public class AuthnResponseBuilderTest {
}
+ @Test
+ public void encryptedAssertionWithDecryption() throws InvalidAssertionEncryptionException, Pvp2MetadataException,
+ XMLParserException, UnmarshallingException, MarshallingException, TransformerException, IOException,
+ SamlAssertionValidationExeption, CredentialsNotAvailableException {
+ final String issuerEntityID = RandomStringUtils.randomAlphabetic(15);
+
+ final IPvp2MetadataProvider metadataProvider =
+ metadataResolverFactory.createMetadataProvider(
+ "classpath:/data/pvp_metadata_junit_keystore.xml", null, "jUnit metadata resolver", null);
+
+ final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ PostBindingTest.class.getResourceAsStream("/data/AuthRequest_without_sig_1.xml"));
+ authnReq.setID("_" + RandomStringUtils.randomAlphanumeric(10));
+
+ final Assertion assertion = (Assertion) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ PostBindingTest.class.getResourceAsStream("/data/Assertion_1.xml"));
+
+ //build response
+ final DateTime now = DateTime.now();
+ final Response response = AuthResponseBuilder.buildResponse(
+ metadataProvider, issuerEntityID, authnReq,
+ now, assertion, authConfig);
+
+
+ //validate
+ Assert.assertNotNull("SAML2 response is null", response);
+ Assert.assertTrue("Assertion not null", response.getAssertions().isEmpty());
+ Assert.assertNotNull("Enc. assertion is null", response.getEncryptedAssertions());
+ Assert.assertFalse("Enc. assertion is empty", response.getEncryptedAssertions().isEmpty());
+ Assert.assertEquals("# enc. assertions wrong", 1, response.getEncryptedAssertions().size());
+
+ Assert.assertEquals("InResponseTo", authnReq.getID(), response.getInResponseTo());
+ Assert.assertEquals("Issuer EntityId", issuerEntityID, response.getIssuer().getValue());
+ Assert.assertNotNull("ResponseId is null", response.getID());
+ Assert.assertFalse("ResponseId is emptry", response.getID().isEmpty());
+
+ final Element responseElement = XMLObjectSupport.getMarshaller(response).marshall(response);
+ final String xmlResp = DomUtils.serializeNode(responseElement);
+ Assert.assertNotNull("XML response is null", xmlResp);
+ Assert.assertFalse("XML response is empty", xmlResp.isEmpty());
+
+ verifyEngine.validateAssertion(response, credentialProvider.getMetaDataSigningCredential(),
+ "https://demo.egiz.gv.at/demoportal_demologin/", "jUnitTest", false);
+
+ }
+
}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/MetadataActionTest.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/MetadataActionTest.java
new file mode 100644
index 00000000..8436a43d
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/MetadataActionTest.java
@@ -0,0 +1,67 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyAuthConfig;
+import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
+import at.gv.egiz.eaaf.modules.pvp2.idp.impl.MetadataAction;
+import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;
+import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine;
+import at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration({"/spring/test_eaaf_pvp.beans.xml"})
+@TestPropertySource(
+ locations = {"/config/config_1.props"})
+public class MetadataActionTest {
+
+ @Autowired private DummyAuthConfig authConfig;
+ @Autowired private PvpMetadataResolverFactory metadataResolverFactory;
+ @Autowired private SamlVerificationEngine verifyEngine;
+ @Autowired private DummyCredentialProvider credentialProvider;
+ @Autowired private MetadataAction action;
+
+ protected MockHttpServletRequest httpReq;
+ protected MockHttpServletResponse httpResp;
+ private TestRequestImpl pendingReq;
+ /**
+ * JUnit class initializer.
+ *
+ * @throws Exception In case of an OpenSAML3 initialization error
+ */
+ @BeforeClass
+ public static void classInitializer() throws Exception {
+ EaafOpenSaml3xInitializer.eaafInitialize();
+
+ }
+
+ /**
+ * Test initializer.
+ *
+ */
+ @Before
+ public void initialize() {
+ httpReq = new MockHttpServletRequest();
+ httpResp = new MockHttpServletResponse();
+
+ pendingReq = new TestRequestImpl();
+
+ }
+
+ @Test
+ public void checkNeedAuthFlag() {
+ Assert.assertFalse("Wrong 'needAuth' flag", action.needAuthentication(pendingReq, httpReq, httpResp));
+
+ }
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/Pvp2SProfileIdpSpringResourceProviderTest.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/Pvp2SProfileIdpSpringResourceProviderTest.java
new file mode 100644
index 00000000..f9aafea9
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/Pvp2SProfileIdpSpringResourceProviderTest.java
@@ -0,0 +1,56 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.springframework.core.io.Resource;
+
+import at.gv.egiz.eaaf.core.test.TestConstants;
+import at.gv.egiz.eaaf.modules.pvp2.idp.Pvp2SProfileIdpSpringResourceProvider;
+
+
+
+@RunWith(BlockJUnit4ClassRunner.class)
+public class Pvp2SProfileIdpSpringResourceProviderTest {
+
+ @Test
+ public void testSpringConfig() {
+ final Pvp2SProfileIdpSpringResourceProvider test =
+ new Pvp2SProfileIdpSpringResourceProvider();
+ for (final Resource el : test.getResourcesToLoad()) {
+ try {
+ IOUtils.toByteArray(el.getInputStream());
+
+ } catch (final IOException e) {
+ Assert.fail("Ressouce: " + el.getFilename() + " not found");
+ }
+
+ }
+
+ Assert.assertNotNull("no Name", test.getName());
+ Assert.assertNull("Find package definitions", test.getPackagesToScan());
+
+ }
+
+ @Test
+ public void testSpILoaderConfig() {
+ final InputStream el = this.getClass().getResourceAsStream(TestConstants.TEST_SPI_LOADER_PATH);
+ try {
+ final String spiFile = IOUtils.toString(el, "UTF-8");
+
+ Assert.assertEquals("Wrong classpath in SPI file",
+ Pvp2SProfileIdpSpringResourceProvider.class.getName(), spiFile);
+
+
+ } catch (final IOException e) {
+ Assert.fail("Ressouce: " + TestConstants.TEST_SPI_LOADER_PATH + " not found");
+
+ }
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyLoALevelMapper.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyLoALevelMapper.java
new file mode 100644
index 00000000..004df86d
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyLoALevelMapper.java
@@ -0,0 +1,25 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy;
+
+import at.gv.egiz.eaaf.core.api.data.ILoALevelMapper;
+
+public class DummyLoALevelMapper implements ILoALevelMapper {
+
+ @Override
+ public String mapToEidasLoa(String qaa) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String mapToSecClass(String qaa) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String mapEidasQaaToStorkQaa(String eidasqaaLevel) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpConfiguration.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpConfiguration.java
new file mode 100644
index 00000000..78e2d700
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpConfiguration.java
@@ -0,0 +1,43 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy;
+
+import java.util.List;
+
+import org.opensaml.saml.saml2.metadata.ContactPerson;
+import org.opensaml.saml.saml2.metadata.Organization;
+
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration;
+
+public class DummyPvpConfiguration implements IPvp2BasicConfiguration {
+
+ @Override
+ public String getIdpEntityId(String authUrl) throws EaafException {
+ return authUrl + "/idp";
+ }
+
+ @Override
+ public String getIdpSsoPostService(String authUrl) throws EaafException {
+ return authUrl + "/sso/post";
+ }
+
+ @Override
+ public String getIdpSsoRedirectService(String authUrl) throws EaafException {
+ return authUrl + "/sso/redirect";
+ }
+
+ @Override
+ public Object getIdpSsoSoapService(String authUrl) throws EaafException {
+ return authUrl + "/sso/soap";
+ }
+
+ @Override
+ public List<ContactPerson> getIdpContacts() throws EaafException {
+ return null;
+ }
+
+ @Override
+ public Organization getIdpOrganisation() throws EaafException {
+ return null;
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpMetadataConfigFactory.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpMetadataConfigFactory.java
new file mode 100644
index 00000000..3f24480b
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummyPvpMetadataConfigFactory.java
@@ -0,0 +1,16 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy;
+
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataConfigurationFactory;
+import at.gv.egiz.eaaf.modules.pvp2.api.utils.IPvp2CredentialProvider;
+import at.gv.egiz.eaaf.modules.pvp2.test.metadata.MetadataBuilderTest;
+
+public class DummyPvpMetadataConfigFactory implements IPvpMetadataConfigurationFactory {
+
+ @Override
+ public IPvpMetadataBuilderConfiguration generateMetadataBuilderConfiguration(String authUrl,
+ IPvp2CredentialProvider pvpIdpCredentials) {
+ return MetadataBuilderTest.idpMetadataConfig(pvpIdpCredentials, false, true);
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummySubjectNameGenerator.java b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummySubjectNameGenerator.java
new file mode 100644
index 00000000..3eaa4c09
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/java/at/gv/egiz/eaaf/modules/pvp2/idp/test/dummy/DummySubjectNameGenerator.java
@@ -0,0 +1,18 @@
+package at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy;
+
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+import at.gv.egiz.eaaf.modules.pvp2.idp.api.builder.ISubjectNameIdGenerator;
+
+public class DummySubjectNameGenerator implements ISubjectNameIdGenerator {
+
+ @Override
+ public Pair<String, String> generateSubjectNameId(IAuthData authData, ISpConfiguration spConfig)
+ throws Pvp2Exception {
+ return Pair.newInstance(authData.getBpk(), authData.getBpkType());
+
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/pvp_metadata_junit_keystore.xml b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/pvp_metadata_junit_keystore.xml
index 96560960..7fdbef90 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/pvp_metadata_junit_keystore.xml
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/data/pvp_metadata_junit_keystore.xml
@@ -71,21 +71,22 @@ ANsmjI2azWiTSFjb7Ou5fnCfbeiJUP0s66m8qS4rYl9L
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
- <ds:X509Certificate>MIIDKzCCAhMCBFrxKO4wDQYJKoZIhvcNAQELBQAwWjELMAkGA1UEBhMCQVQxDTALBgNVBAoMBEVH
-SVoxGDAWBgNVBAsMD2RlbW8uZWdpei5ndi5hdDEiMCAGA1UEAwwZTU9BLUlEIElEUCAoVGVzdC1W
-ZXJzaW9uKTAeFw0xODA1MDgwNDM0NTRaFw0yMTAxMzEwNDM0NTRaMFoxCzAJBgNVBAYTAkFUMQ0w
-CwYDVQQKDARFR0laMRgwFgYDVQQLDA9kZW1vLmVnaXouZ3YuYXQxIjAgBgNVBAMMGU1PQS1JRCBJ
-RFAgKFRlc3QtVmVyc2lvbikwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCaFnqoaYoq
-UptenemC6FiVDg5F2hEjpjix8+ow6/6QhUl2cPOS0uwZHaIvwT/RVbJ9CPdil6+11qaCPfZ+FoY+
-M+ke7TRd2RS1DqFbe1KC0imEnwemyLQrYe5Pm7DNcaY/kHTTq+k0eeGbYH0U/Iopyi0VuN5OWl4F
-Vg45pf7knhXkaimItdjnCXnKcYM91mmltCf6TDgUrz7US7PmgvinnhfBgdITAT4GRr4ehliT+/jt
-1OzHEyWRHanBGIpXNeZNqxgnpnGtaDh4JZuYR8qfH+GRK6dtW2ziej6rGIiUElGVCkXsohgxMNzq
-nWeD9JT8+yyp1XZlyQf+IxhhESQLAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIFejAFQepaEl/kC
-VLvidMR+MXq5LCGHthUiI6eDTQZ+H7lZdHlj547XwEdX15b6Md3h7eSJ4hwlfV4go/0FaoLPzvVq
-itwtYY5htywB3B6ZV34Eyi6C59Gl34XrV8CWxH4KKwLsVAjAy+/p/Xh0q2pzSBkeOChzBMBkjmyc
-2Ue4MEKdL9guzp6+Yc/HL/phHAKYapkVyFwvsdqWOgyRzxAHINko8ExImMMB3xB5a52kfqLcui5O
-fzEhjwLFJaGBMmFCmFGGOUwtIvl/6ZQ2LLzOE9+giVK9WsIgH11Pu+ejPFAbXf8cf4oWhbAfTkiy
-4jpXrp77JXFRSDWddb0yePc=</ds:X509Certificate>
+ <ds:X509Certificate>MIIC+jCCAeKgAwIBAgIEXjF+fTANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJB
+VDENMAsGA1UEBwwERUdJWjEOMAwGA1UECgwFalVuaXQxETAPBgNVBAMMCE1ldGFk
+YXRhMB4XDTIwMDEyOTEyNDU0OVoXDTI2MDEyODEyNDU0OVowPzELMAkGA1UEBhMC
+QVQxDTALBgNVBAcMBEVHSVoxDjAMBgNVBAoMBWpVbml0MREwDwYDVQQDDAhNZXRh
+ZGF0YTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK230G3dxNbNlSYA
+O5Kx/Js0aBAgxMt7q9m+dA35fK/dOvF/GjrqjWsMCnax+no9gLnq6x0gXiJclz6H
+rp/YDOfLrJjMpNL/r0FWT947vbnEj7eT8TdY5d6Yi8AZulZmjiCI5nbZh2zwrP4+
+WqRroLoPhXQj8mDyp26M4xHBBUhLMRc2HV4S+XH4uNZ/vTmb8vBg31XGHCY33gl7
+/KA54JNGxJdN8Dxv6yHYsm91ZfVrX39W0iYLUNhUCkolwuQmjDVfrExM8BTLIONb
+f+erJoCm3A9ghZyDYRQ/e69/UEUqDa6XOzykr88INkQscEiAXCDS+EBPMpKo+t3l
+PIA9r7kCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAh/2mg4S03bdZy1OVtEAudBT9
+YZb9OF34hxPtNbkB/V04wSIg1d4TBr5KDhV7CdiUOxPZzHpS8LUCgfGX306FB6NX
+zh/b67uTOPaE72AB4VIT/Np0fsM7k5WhG9k9NoprIGiqCz2lXcfpZiT+LtSO1vWS
+YI87wR9KOSWjcw/5i5qZIAJuwvLCQj5JtUsmrhHK75222J3TJf4dS/gfN4xfY2rW
+9vcXtH6//8WdWp/zx9V7Z1ZsDb8TDKtBCEGuFDgVeU5ScKtVq8qRoUKD3Ve76cZi
+purO3KrRrVAuZP2EfLkZdHEHqe8GPigNnZ5kTn8V2VJ3iRAQ73hpJRR98tFd0A==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml
index 8c0b8596..99552053 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_core.beans.xml
@@ -22,7 +22,10 @@
<bean id="httpClientFactory"
class="at.gv.egiz.eaaf.core.impl.utils.HttpClientFactory" />
+ <bean id="dummyRevisionLogger"
+ class="at.gv.egiz.eaaf.core.impl.logging.DummyRevisionsLogger" />
+
<bean id="eaafKeyStoreFactory"
- class="at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory" />
+ class="at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory" />
</beans> \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_pvp.beans.xml b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_pvp.beans.xml
index aac94041..2bddd629 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_pvp.beans.xml
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/test/resources/spring/test_eaaf_pvp.beans.xml
@@ -12,9 +12,37 @@
<import resource="test_eaaf_core.beans.xml"/>
<import resource="classpath:/eaaf_pvp.beans.xml"/>
+ <import resource="classpath:/eaaf_pvp_idp.beans.xml"/>
<bean id="dummyCredentialProvider"
class="at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyCredentialProvider" />
+
+ <bean id="dummyChainingMetadataResolver"
+ class="at.gv.egiz.eaaf.modules.pvp2.test.dummy.DummyMetadataProvider" />
+ <bean id="samlVerificationEngine"
+ class="at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine" />
+
+ <bean id="dummyLoALevelMapper"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy.DummyLoALevelMapper" />
+
+ <bean id="dummySubjectNameIdGenerator"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy.DummySubjectNameGenerator" />
+
+ <bean id="dummyPvpBasicConfig"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy.DummyPvpConfiguration" />
+
+ <bean id="dummyMetadataConfigFactor"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.test.dummy.DummyPvpMetadataConfigFactory" />
+
+ <bean id="PVPAuthenticationRequestAction"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.AuthenticationAction">
+ <property name="pvpIdpCredentials" ref="dummyCredentialProvider" />
+ </bean>
+
+ <bean id="pvpMetadataService"
+ class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.MetadataAction" >
+ <property name="pvpIdpCredentials" ref="dummyCredentialProvider" />
+ </bean>
</beans> \ No newline at end of file
diff --git a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java
index a81d9119..c906ca43 100644
--- a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java
+++ b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java
@@ -24,18 +24,6 @@ import java.util.List;
import javax.servlet.http.HttpServletResponse;
-import at.gv.egiz.eaaf.core.api.IRequest;
-import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder;
-import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute;
-import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes;
-import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
-import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding;
-import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding;
-import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestExtensionBuilder;
-import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
-import at.gv.egiz.eaaf.modules.pvp2.sp.api.IPvpAuthnRequestBuilderConfiguruation;
-import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AuthnRequestBuildException;
-
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.opensaml.messaging.encoder.MessageEncodingException;
@@ -62,6 +50,17 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder;
+import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute;
+import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding;
+import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestExtensionBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.sp.api.IPvpAuthnRequestBuilderConfiguruation;
+import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AuthnRequestBuildException;
import net.shibboleth.utilities.java.support.security.SecureRandomIdentifierGenerationStrategy;
/**
@@ -247,10 +246,10 @@ public class PvpAuthnRequestBuilder {
// select message encoder
IEncoder binding = null;
if (endpoint.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
- binding = springContext.getBean("PVPRedirectBinding", RedirectBinding.class);
+ binding = springContext.getBean("PvpRedirectBinding", RedirectBinding.class);
} else if (endpoint.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
- binding = springContext.getBean("PVPPOSTBinding", PostBinding.class);
+ binding = springContext.getBean("PvpPostBinding", PostBinding.class);
} else {
log.warn("Binding: {} is not supported", endpoint.getBinding());