aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas <>2021-03-30 15:08:07 +0200
committerThomas <>2022-03-03 16:31:56 +0100
commit2daed784e006d449de5b6151f6e109ab2a829749 (patch)
tree0d5a6b14f690a0237003020f6e48d143eaf7c5d3
parent1ae77e971928a44dd278eaa473392c35855c4227 (diff)
downloadNational_eIDAS_Gateway-2daed784e006d449de5b6151f6e109ab2a829749.tar.gz
National_eIDAS_Gateway-2daed784e006d449de5b6151f6e109ab2a829749.tar.bz2
National_eIDAS_Gateway-2daed784e006d449de5b6151f6e109ab2a829749.zip
add mandate functionality into eIDAS out-going process
-rw-r--r--connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java182
-rw-r--r--connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthenticationDataBuilderTest.java206
-rw-r--r--connector_lib/src/main/java/at/asitplus/eidas/specific/connector/config/ServiceProviderConfiguration.java6
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java6
-rw-r--r--eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthConstants.java58
-rw-r--r--eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/ReceiveFromIdAustriaSystemTask.java29
-rw-r--r--eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java68
-rw-r--r--eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthMetadataControllerFirstTest.java4
-rw-r--r--eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/ReceiveAuthnResponseTaskTest.java102
-rw-r--r--eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/RequestIdAustriaSystemTaskTest.java45
-rw-r--r--eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_jur.xml63
-rw-r--r--eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_nat.xml66
-rw-r--r--eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java16
-rw-r--r--eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java32
-rw-r--r--eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java89
-rw-r--r--eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java95
-rw-r--r--eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java196
17 files changed, 1160 insertions, 103 deletions
diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java
index 2e70893b..629d015e 100644
--- a/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java
+++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java
@@ -24,19 +24,31 @@
package at.asitplus.eidas.specific.connector.builder;
import java.util.Date;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
+import com.google.common.collect.Streams;
+
import at.asitplus.eidas.specific.connector.MsEidasNodeConstants;
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants;
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions.EidIdentityStatusLevelValues;
import at.gv.egiz.eaaf.core.api.idp.IAuthData;
import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
import at.gv.egiz.eaaf.core.api.idp.auth.data.IAuthProcessDataContainer;
+import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;
import at.gv.egiz.eaaf.core.exceptions.EaafBuilderException;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
+import at.gv.egiz.eaaf.core.impl.builder.BpkBuilder;
import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.core.impl.data.Triple;
import at.gv.egiz.eaaf.core.impl.idp.AuthenticationData;
import at.gv.egiz.eaaf.core.impl.idp.EidAuthenticationData;
import at.gv.egiz.eaaf.core.impl.idp.auth.builder.AbstractAuthenticationDataBuilder;
@@ -46,55 +58,59 @@ import lombok.extern.slf4j.Slf4j;
@Service("AuthenticationDataBuilder")
@Slf4j
public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder {
-
+
+ private static final String ERROR_B11 = "builder.11";
+
@Override
- protected IAuthData buildDeprecatedAuthData(IRequest pendingReq) throws EaafException {
+ protected IAuthData buildDeprecatedAuthData(IRequest pendingReq) throws EaafException {
final EidAuthProcessDataWrapper authProcessData =
- pendingReq.getSessionData(EidAuthProcessDataWrapper.class);
- EidAuthenticationData authData = new EidAuthenticationData();
-
- //set basis infos
+ pendingReq.getSessionData(EidAuthProcessDataWrapper.class);
+ final EidAuthenticationData authData = new EidAuthenticationData();
+
+ // set basis infos
super.generateDeprecatedBasicAuthData(authData, pendingReq, authProcessData);
-
+
// set specific informations
authData.setSsoSessionValidTo(
new Date(new Date().getTime() + MsEidasNodeConstants.DEFAULT_PVP_ASSERTION_VALIDITY * 60 * 1000));
-
- authData.setEidStatus(authProcessData.isTestIdentity()
- ? EidIdentityStatusLevelValues.TESTIDENTITY : EidIdentityStatusLevelValues.IDENTITY);
-
+
+ authData.setEidStatus(authProcessData.isTestIdentity()
+ ? EidIdentityStatusLevelValues.TESTIDENTITY
+ : EidIdentityStatusLevelValues.IDENTITY);
+
return authData;
}
@Override
- protected void buildServiceSpecificAuthenticationData(IAuthData authData, IRequest pendingReq)
+ protected void buildServiceSpecificAuthenticationData(IAuthData authData, IRequest pendingReq)
throws EaafException {
if (authData instanceof EidAuthenticationData) {
- ((EidAuthenticationData)authData).setGenericData(
- ExtendedPvpAttributeDefinitions.EID_PII_TRANSACTION_ID_NAME,
+ ((EidAuthenticationData) authData).setGenericData(
+ ExtendedPvpAttributeDefinitions.EID_PII_TRANSACTION_ID_NAME,
pendingReq.getUniquePiiTransactionIdentifier());
log.trace("Inject piiTransactionId: {} into AuthData", pendingReq.getUniquePiiTransactionIdentifier());
-
+
// set specific informations
- ((EidAuthenticationData)authData).setSsoSessionValidTo(
+ ((EidAuthenticationData) authData).setSsoSessionValidTo(
new Date(new Date().getTime() + MsEidasNodeConstants.DEFAULT_PVP_ASSERTION_VALIDITY * 60 * 1000));
- //set E-ID status-level
+ // set E-ID status-level
final EidAuthProcessDataWrapper authProcessData =
- pendingReq.getSessionData(EidAuthProcessDataWrapper.class);
- ((EidAuthenticationData)authData).setEidStatus(authProcessData.isTestIdentity()
- ? EidIdentityStatusLevelValues.TESTIDENTITY : EidIdentityStatusLevelValues.IDENTITY);
-
-
-
-
+ pendingReq.getSessionData(EidAuthProcessDataWrapper.class);
+ ((EidAuthenticationData) authData).setEidStatus(authProcessData.isTestIdentity()
+ ? EidIdentityStatusLevelValues.TESTIDENTITY
+ : EidIdentityStatusLevelValues.IDENTITY);
+
+ // handle mandate informations
+ buildMandateInformation((EidAuthenticationData) authData, pendingReq, authProcessData);
+
} else {
- throw new RuntimeException("Can not inject PiiTransactionId because AuthData is of unknown type: "
+ throw new RuntimeException("Can not inject PiiTransactionId because AuthData is of unknown type: "
+ authData.getClass().getName());
-
+
}
-
+
}
@Override
@@ -123,4 +139,116 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder
}
+ private void buildMandateInformation(EidAuthenticationData authData, IRequest pendingReq,
+ EidAuthProcessDataWrapper authProcessData) throws EaafAuthenticationException, EaafBuilderException,
+ EaafStorageException {
+ authData.setUseMandate(authProcessData.isMandateUsed());
+ if (authProcessData.isMandateUsed()) {
+ log.debug("Build mandate-releated authentication data ... ");
+ if (authProcessData.isForeigner()) {
+ buildMandateInformationForEidasIncoming();
+
+ } else {
+ buildMandateInformationForEidasOutgoing(authData, pendingReq, authProcessData);
+
+ }
+
+ // inject mandate information into authdata
+ final Set<String> mandateAttributes = Streams.concat(
+ IdAustriaAuthConstants.DEFAULT_REQUIRED_MANDATE_NAT_PVP_ATTRIBUTES.stream(),
+ IdAustriaAuthConstants.DEFAULT_REQUIRED_MANDATE_JUR_PVP_ATTRIBUTES.stream())
+ .map(el -> el.getFirst())
+ .collect(Collectors.toSet());
+
+ authProcessData.getGenericSessionDataStream()
+ .filter(el -> mandateAttributes.contains(el.getKey()))
+ .forEach(el -> {
+ try {
+ authData.setGenericData(el.getKey(), el.getValue());
+
+ } catch (final EaafStorageException e) {
+ log.error("Can not store attribute: {} into session.", el.getKey(), e);
+ throw new RuntimeException(e);
+
+ }
+ });
+ }
+ }
+
+ private void buildMandateInformationForEidasIncoming() {
+ log.debug("Find eIDAS incoming process. Generated mandate-information for ID-Austria system ... ");
+
+ // TODO: implement IDA specific processing of foreign mandate
+
+ }
+
+ private void buildMandateInformationForEidasOutgoing(EidAuthenticationData authData, IRequest pendingReq,
+ EidAuthProcessDataWrapper authProcessData) throws EaafAuthenticationException, EaafBuilderException,
+ EaafStorageException {
+ log.debug("Find eIDAS outgoing process. Generated mandate-information for other country ... ");
+ if (authProcessData.getGenericDataFromSession(
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME) != null) {
+ final Optional<Triple<String, String, Boolean>> missingAttribute =
+ IdAustriaAuthConstants.DEFAULT_REQUIRED_MANDATE_NAT_PVP_ATTRIBUTES.stream()
+ .filter(el -> authProcessData.getGenericDataFromSession(el.getFirst()) == null)
+ .findFirst();
+ if (missingAttribute.isPresent()) {
+ log.error("ID-Austria response contains not all attributes for nat. person mandator. Missing: {}",
+ missingAttribute.get().getFirst());
+ throw new EaafAuthenticationException(ERROR_B11, new Object[] { "Nat. person mandate" });
+
+ } else {
+ log.trace("Find nat. person mandate. Mandate can be used as it is ");
+ authData.setGenericData(MsProxyServiceConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER,
+ extractBpkFromResponse(authProcessData.getGenericDataFromSession(
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, String.class)));
+
+ }
+
+ } else {
+ final Optional<Triple<String, String, Boolean>> missingAttribute =
+ IdAustriaAuthConstants.DEFAULT_REQUIRED_MANDATE_JUR_PVP_ATTRIBUTES.stream()
+ .filter(el -> authProcessData.getGenericDataFromSession(el.getFirst()) == null)
+ .findFirst();
+ if (missingAttribute.isPresent()) {
+ log.error("ID-Austria response contains not all attributes for legal. person mandator. Missing: {}",
+ missingAttribute.get().getFirst());
+ throw new EaafAuthenticationException(ERROR_B11, new Object[] { "Legal. person mandate" });
+
+ } else {
+ log.trace(
+ "Find jur. person mandate. Generate eIDAS identifier from legal-person sourcePin and type ... ");
+ final String sourcePin = authProcessData.getGenericDataFromSession(
+ PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, String.class);
+ final String sourcePinType = authProcessData.getGenericDataFromSession(
+ PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME, String.class);
+
+ // TODO: check if we should to this in such a way!
+ final Pair<String, String> leagalPersonIdentifier =
+ BpkBuilder.generateAreaSpecificPersonIdentifier(
+ sourcePinType + sourcePin,
+ sourcePinType,
+ pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier());
+
+ log.debug("Use legal-person eIDAS identifer: {} from baseId: {} and baseIdType: {}",
+ leagalPersonIdentifier.getFirst(), sourcePin, sourcePinType);
+ authData.setGenericData(MsProxyServiceConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER,
+ leagalPersonIdentifier.getFirst());
+
+ }
+ }
+ }
+
+ private String extractBpkFromResponse(String pvpBpkAttrValue) {
+ final String[] split = pvpBpkAttrValue.split(":", 2);
+ if (split.length == 2) {
+ return split[1];
+
+ } else {
+ log.warn("PVP bPK attribute: {} has wrong format. Use it as it is.", pvpBpkAttrValue);
+ return pvpBpkAttrValue;
+
+ }
+ }
+
}
diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthenticationDataBuilderTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthenticationDataBuilderTest.java
index 552c448e..277138ef 100644
--- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthenticationDataBuilderTest.java
+++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthenticationDataBuilderTest.java
@@ -1,6 +1,10 @@
package at.asitplus.eidas.specific.connector.test.utils;
import static at.asitplus.eidas.specific.connector.MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.security.PublicKey;
@@ -176,9 +180,169 @@ public class AuthenticationDataBuilderTest {
Assert.assertEquals("testIdentity flag",
isTestIdentity ? EidIdentityStatusLevelValues.TESTIDENTITY : EidIdentityStatusLevelValues.IDENTITY,
- ((EidAuthenticationData)authData).getEidStatus());
+ ((EidAuthenticationData)authData).getEidStatus());
+ assertFalse("mandate flag", ((EidAuthenticationData)authData).isUseMandate());
+
+ }
+
+ @Test
+ public void eidasProxyModeWithJurMandate() throws EaafAuthenticationException, EaafStorageException {
+ // initialize state
+ injectRepresentativeInfosIntoSession();
+
+ String commonMandate = RandomStringUtils.randomAlphabetic(10);
+
+ // set constant country-code and sourcePin to check hashed eIDAS identifier
+ String sourcePinMandate = "asfdsadfsadfsafsdafsadfasr";
+ spConfig.put("target", EaafConstants.URN_PREFIX_EIDAS + "AT+EE");
+
+ // set nat. person mandate information
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, commonMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, sourcePinMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME,
+ EaafConstants.URN_PREFIX_BASEID + "+XFN");
+
+ // execute test
+ IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq);
+
+
+ // validate state
+ Assert.assertNotNull("AuthData null", authData);
+ assertTrue("mandate flag", ((EidAuthenticationData)authData).isUseMandate());
+
+ //check mandate informations
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, commonMandate);
+ checkGenericAttribute(authData, MsProxyServiceConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER,
+ "AT/EE/oaAGaV/zIHSf6rcB0TIOqjWPoOU=");
+
+ }
+
+ @Test
+ public void eidasProxyModeWithJurMandateMissingAttribute() throws EaafAuthenticationException, EaafStorageException {
+ // initialize state
+ injectRepresentativeInfosIntoSession();
+
+ // set constant country-code and sourcePin to check hashed eIDAS identifier
+ String sourcePinMandate = "asfdsadfsadfsafsdafsadfasr";
+ spConfig.put("target", EaafConstants.URN_PREFIX_EIDAS + "AT+EE");
+
+ // set nat. person mandate information
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, sourcePinMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME,
+ EaafConstants.URN_PREFIX_BASEID + "+XFN");
+
+ // execute test
+ // execute test
+ EaafAuthenticationException error = assertThrows(EaafAuthenticationException.class,
+ () -> authenticationDataBuilder.buildAuthenticationData(pendingReq));
+ Assert.assertEquals("wrong errorId", "builder.11", error.getErrorId());
+
+ }
+
+ @Test
+ public void eidasProxyModeWithNatMandate() throws EaafAuthenticationException, EaafStorageException {
+ // initialize state
+ injectRepresentativeInfosIntoSession();
+
+ String givenNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String familyNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String dateOfBirthMandate = "1957-09-15";
+ String bpkMandate = RandomStringUtils.randomAlphanumeric(10);
+
+ // set nat. person mandate information
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, dateOfBirthMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, "AT+XX:" + bpkMandate);
+
+ // execute test
+ IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq);
+
+
+ // validate state
+ Assert.assertNotNull("AuthData null", authData);
+ assertTrue("mandate flag", ((EidAuthenticationData)authData).isUseMandate());
+
+ //check mandate informations
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, "1957-09-15");
+ checkGenericAttribute(authData, MsProxyServiceConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER, bpkMandate);
+
+ }
+
+ @Test
+ public void eidasProxyModeWithNatMandateWrongBpkFormat() throws EaafAuthenticationException, EaafStorageException {
+ // initialize state
+ injectRepresentativeInfosIntoSession();
+
+ String givenNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String familyNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String dateOfBirthMandate = "1957-09-15";
+ String bpkMandate = RandomStringUtils.randomAlphanumeric(10);
+
+ // set nat. person mandate information
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, dateOfBirthMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, bpkMandate);
+
+ // execute test
+ IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq);
+
+
+ // validate state
+ Assert.assertNotNull("AuthData null", authData);
+ assertTrue("mandate flag", ((EidAuthenticationData)authData).isUseMandate());
+ //check mandate informations
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, "1957-09-15");
+ checkGenericAttribute(authData, MsProxyServiceConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER, bpkMandate);
+
+ }
+
+ @Test
+ public void eidasProxyModeWithNatMandateMissingAttribute() throws EaafAuthenticationException, EaafStorageException {
+ // initialize state
+ injectRepresentativeInfosIntoSession();
+
+ String familyNameMandate = RandomStringUtils.randomAlphabetic(10);
+ String dateOfBirthMandate = "1957-09-15";
+ String bpkMandate = RandomStringUtils.randomAlphanumeric(10);
+
+ // set nat. person mandate information
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, dateOfBirthMandate);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, bpkMandate);
+ // execute test
+ EaafAuthenticationException error = assertThrows(EaafAuthenticationException.class,
+ () -> authenticationDataBuilder.buildAuthenticationData(pendingReq));
+ Assert.assertEquals("wrong errorId", "builder.11", error.getErrorId());
+
}
@Test
@@ -203,7 +367,7 @@ public class AuthenticationDataBuilderTest {
Assert.assertEquals("testIdentity flag",
isTestIdentity ? EidIdentityStatusLevelValues.TESTIDENTITY : EidIdentityStatusLevelValues.IDENTITY,
((EidAuthenticationData)authData).getEidStatus());
-
+
String authBlock = authData.getGenericData(Constants.SZR_AUTHBLOCK, String.class);
String eidasBind = authData.getGenericData(Constants.EIDAS_BIND, String.class);
@@ -276,6 +440,44 @@ public class AuthenticationDataBuilderTest {
}
+ private void injectRepresentativeInfosIntoSession() throws EaafStorageException {
+ boolean isTestIdentity = RandomUtils.nextBoolean();
+ pendingReq.getSessionData(EidAuthProcessDataWrapper.class).setTestIdentity(isTestIdentity);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setEidProcess(true);
+
+ String givenName = RandomStringUtils.randomAlphabetic(10);
+ String familyName = RandomStringUtils.randomAlphabetic(10);
+ String dateOfBirth = "1956-12-08";
+ String bpk = RandomStringUtils.randomAlphanumeric(10);
+ String cc = pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .getGenericDataFromSession(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, String.class);
+ String spC = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ spConfig.put("target", EaafConstants.URN_PREFIX_EIDAS + cc + "+" + spC);
+
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setEidProcess(true);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setForeigner(false);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.GIVEN_NAME_NAME, givenName);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, familyName);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.BIRTHDATE_NAME, dateOfBirth);
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, bpk);
+
+ //set LoA level attribute instead of explicit session-data
+ pendingReq.getSessionData(AuthProcessDataWrapper.class)
+ .setGenericDataToSession(PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME,
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).getQaaLevel());
+ pendingReq.getSessionData(AuthProcessDataWrapper.class).setQaaLevel(null);
+
+ }
+
+ private void checkGenericAttribute(IAuthData authData, String attrName, String expected) {
+ assertEquals("Wrong: " + attrName, expected, authData.getGenericData(attrName, String.class));
+
+ }
+
private IIdentityLink buildDummyIdl() {
return new IIdentityLink() {
diff --git a/connector_lib/src/main/java/at/asitplus/eidas/specific/connector/config/ServiceProviderConfiguration.java b/connector_lib/src/main/java/at/asitplus/eidas/specific/connector/config/ServiceProviderConfiguration.java
index 362d0244..0f72203b 100644
--- a/connector_lib/src/main/java/at/asitplus/eidas/specific/connector/config/ServiceProviderConfiguration.java
+++ b/connector_lib/src/main/java/at/asitplus/eidas/specific/connector/config/ServiceProviderConfiguration.java
@@ -37,6 +37,8 @@ import at.gv.egiz.eaaf.core.api.data.EaafConstants;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
import at.gv.egiz.eaaf.core.impl.idp.conf.SpConfigurationImpl;
+import lombok.Getter;
+import lombok.Setter;
public class ServiceProviderConfiguration extends SpConfigurationImpl {
private static final long serialVersionUID = 1L;
@@ -46,6 +48,10 @@ public class ServiceProviderConfiguration extends SpConfigurationImpl {
private String bpkTargetIdentifier;
private String loaMachtingMode = EaafConstants.EIDAS_LOA_MATCHING_MINIMUM;
+ @Setter
+ @Getter
+ private List<String> mandateProfiles;
+
public ServiceProviderConfiguration(Map<String, String> spConfig, IConfiguration authConfig) {
super(spConfig, authConfig);
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java
index e2200ed1..f0d57229 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java
@@ -156,6 +156,12 @@ public class Constants {
public static final String eIDAS_ATTR_LEGALPERSONIDENTIFIER = "LegalPersonIdentifier";
public static final String eIDAS_ATTR_LEGALNAME = "LegalName";
+ public static final String eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER = "RepresentativePersonIdentifier";
+ public static final String eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH = "RepresentativeDateOfBirth";
+ public static final String eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME = "RepresentativeFirstName";
+ public static final String eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME = "RepresentativeFamilyName";
+
+
public static final String eIDAS_REQ_PARAM_SECTOR_PUBLIC = "public";
public static final String eIDAS_REQ_PARAM_SECTOR_PRIVATE = "private";
diff --git a/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthConstants.java b/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthConstants.java
index 18eaee4b..982bfb4f 100644
--- a/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthConstants.java
+++ b/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/IdAustriaAuthConstants.java
@@ -3,6 +3,8 @@ package at.asitplus.eidas.specific.modules.auth.idaustria;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
import at.gv.egiz.eaaf.core.impl.data.Triple;
@@ -69,6 +71,36 @@ public class IdAustriaAuthConstants {
public static final String CONFIG_PROPS_REQUIRED_PVP_ATTRIBUTES_LIST = CONFIG_PROPS_PREFIX
+ "required.additional.attributes";
+ public static final List<Triple<String, String, Boolean>> DEFAULT_REQUIRED_MANDATE_NAT_PVP_ATTRIBUTES =
+ Collections.unmodifiableList(new ArrayList<Triple<String, String, Boolean>>() {
+ private static final long serialVersionUID = 1L;
+ {
+ add(Triple.newInstance(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_FRIENDLY_NAME, false));
+ add(Triple.newInstance(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_FRIENDLY_NAME, false));
+ add(Triple.newInstance(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_FRIENDLY_NAME, false));
+ add(Triple.newInstance(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME,
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_FRIENDLY_NAME, false));
+
+ }
+ });
+
+ public static final List<Triple<String, String, Boolean>> DEFAULT_REQUIRED_MANDATE_JUR_PVP_ATTRIBUTES =
+ Collections.unmodifiableList(new ArrayList<Triple<String, String, Boolean>>() {
+ private static final long serialVersionUID = 1L;
+ {
+ add(Triple.newInstance(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME,
+ PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_FRIENDLY_NAME, false));
+ add(Triple.newInstance(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME,
+ PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_FRIENDLY_NAME, false));
+ add(Triple.newInstance(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME,
+ PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_FRIENDLY_NAME, false));
+
+ }
+ });
+
public static final List<Triple<String, String, Boolean>> DEFAULT_REQUIRED_PVP_ATTRIBUTES =
Collections.unmodifiableList(new ArrayList<Triple<String, String, Boolean>>() {
private static final long serialVersionUID = 1L;
@@ -93,19 +125,21 @@ public class IdAustriaAuthConstants {
add(Triple.newInstance(PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME,
PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_FRIENDLY_NAME, false));
+ // mandate attributes
+ add(Triple.newInstance(PvpAttributeDefinitions.MANDATE_TYPE_NAME,
+ PvpAttributeDefinitions.MANDATE_TYPE_FRIENDLY_NAME, false));
+ add(Triple.newInstance(PvpAttributeDefinitions.MANDATE_TYPE_OID_NAME,
+ PvpAttributeDefinitions.MANDATE_TYPE_OID_FRIENDLY_NAME, false));
+ addAll(DEFAULT_REQUIRED_MANDATE_JUR_PVP_ATTRIBUTES);
+ addAll(DEFAULT_REQUIRED_MANDATE_NAT_PVP_ATTRIBUTES);
+
}
});
- public static final List<String> DEFAULT_REQUIRED_PVP_ATTRIBUTE_NAMES =
- Collections.unmodifiableList(new ArrayList<String>() {
- private static final long serialVersionUID = 1L;
- {
- for (final Triple<String, String, Boolean> el : DEFAULT_REQUIRED_PVP_ATTRIBUTES) {
- if (el.getThird()) {
- add(el.getFirst());
-
- }
- }
- }
- });
+ public static final Set<String> DEFAULT_REQUIRED_PVP_ATTRIBUTE_NAMES =
+ DEFAULT_REQUIRED_PVP_ATTRIBUTES.stream()
+ .filter(el -> el.getThird())
+ .map(el -> el.getFirst())
+ .collect(Collectors.toSet());
+
}
diff --git a/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/ReceiveFromIdAustriaSystemTask.java b/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/ReceiveFromIdAustriaSystemTask.java
index 5dc04800..2141fee8 100644
--- a/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/ReceiveFromIdAustriaSystemTask.java
+++ b/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/ReceiveFromIdAustriaSystemTask.java
@@ -1,7 +1,6 @@
package at.asitplus.eidas.specific.modules.auth.idaustria.tasks;
import java.io.IOException;
-import java.util.List;
import java.util.Set;
import javax.naming.ConfigurationException;
@@ -211,7 +210,7 @@ public class ReceiveFromIdAustriaSystemTask extends AbstractAuthServletTask {
private void getAuthDataFromInterfederation(AssertionAttributeExtractor extractor)
throws EaafBuilderException, ConfigurationException {
- final List<String> requiredEidasNodeAttributes =
+ final Set<String> requiredEidasNodeAttributes =
IdAustriaAuthConstants.DEFAULT_REQUIRED_PVP_ATTRIBUTE_NAMES;
try {
// check if all attributes are include
@@ -238,7 +237,7 @@ public class ReceiveFromIdAustriaSystemTask extends AbstractAuthServletTask {
extractor.getSingleAttributeValue(attrName));
}
-
+
// set foreigner flag
session.setForeigner(false);
@@ -248,7 +247,9 @@ public class ReceiveFromIdAustriaSystemTask extends AbstractAuthServletTask {
// set IssuerInstant from Assertion
session.setIssueInstant(extractor.getAssertionIssuingDate());
- // TODO: add mandates if SEMPER are integrated
+ // set mandate flag
+ session.setUseMandates(checkIfMandateInformationIsAvailable(extractor));
+
} catch (final EaafException | IOException e) {
throw new EaafBuilderException(ERROR_PVP_06, null, e.getMessage(), e);
@@ -256,6 +257,20 @@ public class ReceiveFromIdAustriaSystemTask extends AbstractAuthServletTask {
}
}
+
+ /**
+ * Check if mandate information is available.
+ *
+ * @param extractor Assertion from ID Austria system.
+ * @return <code>true</code> if mandate was used, otherwise <code>false</code>
+ */
+ private boolean checkIfMandateInformationIsAvailable(AssertionAttributeExtractor extractor) {
+ boolean isMandateIncluded = extractor.containsAttribute(PvpAttributeDefinitions.MANDATE_TYPE_NAME);
+ log.debug("Response from ID-Austria system contains mandate information. Switch to mandate-mode ... ");
+ return isMandateIncluded;
+
+ }
+
private void validateResponseAttributes(AssertionAttributeExtractor extractor)
throws EaafAuthenticationException {
final String bpkTarget = extractor.getSingleAttributeValue(
@@ -295,14 +310,14 @@ public class ReceiveFromIdAustriaSystemTask extends AbstractAuthServletTask {
log.trace("Find bPK attribute. Extract eIDAS identifier ... ");
session.setGenericDataToSession(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER,
extractBpkFromResponse(attrValue));
-
- } else {
+
+ } else {
session.setGenericDataToSession(attrName, attrValue);
}
}
-
+
private String extractBpkFromResponse(String pvpBpkAttrValue) {
final String[] split = pvpBpkAttrValue.split(":", 2);
if (split.length == 2) {
diff --git a/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java b/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java
index fc46ac8b..8151b429 100644
--- a/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java
+++ b/eidas_modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java
@@ -14,6 +14,7 @@ import org.opensaml.saml.saml2.core.Attribute;
import org.opensaml.saml.saml2.metadata.EntityDescriptor;
import org.springframework.beans.factory.annotation.Autowired;
+import at.asitplus.eidas.specific.connector.config.ServiceProviderConfiguration;
import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
import at.asitplus.eidas.specific.modules.auth.idaustria.config.IdAustriaAuthRequestBuilderConfiguration;
import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthCredentialProvider;
@@ -147,63 +148,52 @@ public class RequestIdAustriaSystemTask extends AbstractAuthServletTask {
final List<EaafRequestedAttribute> attributs = new ArrayList<>();
//build attribute that contains the unique identifier of the eIDAS-Connector
- final Attribute attrEidasConnectorId = PvpAttributeBuilder.buildEmptyAttribute(
- ExtendedPvpAttributeDefinitions.EIDAS_CONNECTOR_UNIQUEID_NAME);
- final EaafRequestedAttribute attrEidasConnectorIdReqAttr = Saml2Utils.generateReqAuthnAttributeSimple(
- attrEidasConnectorId,
- true,
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.EIDAS_CONNECTOR_UNIQUEID_NAME,
pendingReq.getServiceProviderConfiguration().getUniqueIdentifier());
- attributs.add(attrEidasConnectorIdReqAttr);
-
-
+
// build EID sector for identification attribute
- final Attribute attr = PvpAttributeBuilder.buildEmptyAttribute(
- PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME);
- final EaafRequestedAttribute bpkTargetReqAttr = Saml2Utils.generateReqAuthnAttributeSimple(
- attr,
- true,
+ injectAttribute(attributs, PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME,
pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier());
- attributs.add(bpkTargetReqAttr);
-
// set requested LoA as attribute
- final Attribute loaAttr = PvpAttributeBuilder.buildEmptyAttribute(
- PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME);
- final EaafRequestedAttribute loaReqAttr = Saml2Utils.generateReqAuthnAttributeSimple(
- loaAttr,
- true,
+ injectAttribute(attributs, PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME,
selectHighestLoa(pendingReq.getServiceProviderConfiguration().getRequiredLoA()));
- attributs.add(loaReqAttr);
-
-
+
//set ProviderName if available
String providerName = ((ProxyServicePendingRequest)pendingReq).getEidasRequest().getProviderName();
if (StringUtils.isNotEmpty(providerName)) {
- final Attribute providerNameAttr = PvpAttributeBuilder.buildEmptyAttribute(
- ExtendedPvpAttributeDefinitions.SP_FRIENDLYNAME_NAME);
- final EaafRequestedAttribute providerNameReqAttr = Saml2Utils.generateReqAuthnAttributeSimple(
- providerNameAttr,
- true,
- providerName);
- attributs.add(providerNameReqAttr);
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.SP_FRIENDLYNAME_NAME, providerName);
}
-
-
+
//set ProviderName if available
String requesterId = ((ProxyServicePendingRequest)pendingReq).getEidasRequest().getRequesterId();
if (StringUtils.isNotEmpty(requesterId)) {
- final Attribute requesterIdAttr = PvpAttributeBuilder.buildEmptyAttribute(
- ExtendedPvpAttributeDefinitions.SP_UNIQUEID_NAME);
- final EaafRequestedAttribute requesterIdReqAttr = Saml2Utils.generateReqAuthnAttributeSimple(
- requesterIdAttr,
- true,
- requesterId);
- attributs.add(requesterIdReqAttr);
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.SP_UNIQUEID_NAME, requesterId);
}
+ //set mandate profiles
+ List<String> mandateProfiles =
+ pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).getMandateProfiles();
+ if (mandateProfiles != null && !mandateProfiles.isEmpty()) {
+ log.debug("Set mandate-profiles attribute into ID-Austria request");
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.SP_USED_MANDATE_PROFILES_NAME,
+ StringUtils.join(mandateProfiles, ","));
+
+ }
+
return attributs;
}
+ private void injectAttribute(List<EaafRequestedAttribute> attributs, String attributeName, String attributeValue) {
+ final Attribute requesterIdAttr = PvpAttributeBuilder.buildEmptyAttribute(attributeName);
+ final EaafRequestedAttribute requesterIdReqAttr = Saml2Utils.generateReqAuthnAttributeSimple(
+ requesterIdAttr,
+ true,
+ attributeValue);
+ attributs.add(requesterIdReqAttr);
+
+ }
+
}
diff --git a/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthMetadataControllerFirstTest.java b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthMetadataControllerFirstTest.java
index ef0c4da0..d2a2556b 100644
--- a/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthMetadataControllerFirstTest.java
+++ b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/controller/IdAustriaAuthMetadataControllerFirstTest.java
@@ -94,7 +94,7 @@ public class IdAustriaAuthMetadataControllerFirstTest {
controller.getSpMetadata(httpReq, httpResp);
//check result
- validateResponse(7);
+ validateResponse(16);
}
@@ -117,7 +117,7 @@ public class IdAustriaAuthMetadataControllerFirstTest {
controller.getSpMetadata(httpReq, httpResp);
//check result
- validateResponse(8);
+ validateResponse(17);
}
diff --git a/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/ReceiveAuthnResponseTaskTest.java b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/ReceiveAuthnResponseTaskTest.java
index a0446ad9..b3a5130f 100644
--- a/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/ReceiveAuthnResponseTaskTest.java
+++ b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/ReceiveAuthnResponseTaskTest.java
@@ -1,6 +1,9 @@
package at.asitplus.eidas.specific.modules.auth.idaustria.test.task;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.Arrays;
@@ -536,6 +539,8 @@ public class ReceiveAuthnResponseTaskTest {
Assert.assertNotNull("pendingReq not stored", storedReq);
final AuthProcessDataWrapper session = pendingReq.getSessionData(AuthProcessDataWrapper.class);
Assert.assertFalse("foreigner flag", session.isForeigner());
+ assertTrue("eidProcess flag", session.isEidProcess());
+ assertFalse("useMandate flag", session.isMandateUsed());
checkAttributeInSession(session,PvpAttributeDefinitions.GIVEN_NAME_NAME, "Max");
checkAttributeInSession(session,PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Mustermann");
@@ -662,6 +667,103 @@ public class ReceiveAuthnResponseTaskTest {
}
+ @Test
+ public void httpPostValidSignedAssertionEidValidWithJurMandate() throws IOException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException, TaskExecutionException, EaafException {
+
+ oaParam.setBpkTargetIdentifier(EaafConstants.URN_PREFIX_EIDAS + "AT+XX");
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_with_EID_with_mandate_jur.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ // perform task
+ task.execute(pendingReq, executionContext);
+
+ // validate state
+ IRequest storedReq = storage.getPendingRequest(pendingReq.getPendingRequestId());
+ Assert.assertNotNull("pendingReq not stored", storedReq);
+ final AuthProcessDataWrapper session = pendingReq.getSessionData(AuthProcessDataWrapper.class);
+ Assert.assertFalse("foreigner flag", session.isForeigner());
+ assertTrue("eidProcess flag", session.isEidProcess());
+ assertTrue("useMandate flag", session.isMandateUsed());
+
+ checkAttributeInSession(session, PvpAttributeDefinitions.GIVEN_NAME_NAME, "Max");
+ checkAttributeInSession(session, PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Mustermann");
+ checkAttributeInSession(session, PvpAttributeDefinitions.BIRTHDATE_NAME, "1940-01-01");
+ checkAttributeInSession(session, PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, "http://eidas.europa.eu/LoA/high");
+ checkAttributeInSession(session, PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, "AT");
+
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_TYPE_NAME, "Generalvollmacht");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, "Testfirma");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, "999999m");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME, "urn:publicid:gv.at:baseid+XERSB");
+
+ //pre-generated eIDAS identifer
+ checkAttributeInSession(session, MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, "QVGm48cqcM4UcyhDTNGYmVdrIoY=");
+ assertNull("find nat. person bpk for mandator", session.getGenericDataFromSession(
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, String.class));
+
+
+ }
+
+ @Test
+ public void httpPostValidSignedAssertionEidValidWithNatMandate() throws IOException, XMLParserException, UnmarshallingException,
+ MarshallingException, TransformerException, TaskExecutionException, EaafException {
+
+ oaParam.setBpkTargetIdentifier(EaafConstants.URN_PREFIX_EIDAS + "AT+XX");
+
+ metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(
+ METADATA_PATH, null, "jUnit IDP", null));
+
+ final Response response = initializeResponse(
+ "classpath:/data/idp_metadata_classpath_entity.xml",
+ "/data/Response_with_EID_with_mandate_nat.xml",
+ credentialProvider.getMessageSigningCredential(),
+ true);
+ httpReq.addParameter("SAMLResponse", Base64.getEncoder().encodeToString(
+ DomUtils.serializeNode(XMLObjectSupport.getMarshaller(response).marshall(response)).getBytes(
+ "UTF-8")));
+
+ // perform task
+ task.execute(pendingReq, executionContext);
+
+ // validate state
+ IRequest storedReq = storage.getPendingRequest(pendingReq.getPendingRequestId());
+ Assert.assertNotNull("pendingReq not stored", storedReq);
+ final AuthProcessDataWrapper session = pendingReq.getSessionData(AuthProcessDataWrapper.class);
+ Assert.assertFalse("foreigner flag", session.isForeigner());
+ assertTrue("eidProcess flag", session.isEidProcess());
+ assertTrue("useMandate flag", session.isMandateUsed());
+
+ checkAttributeInSession(session, PvpAttributeDefinitions.GIVEN_NAME_NAME, "Max");
+ checkAttributeInSession(session, PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Mustermann");
+ checkAttributeInSession(session, PvpAttributeDefinitions.BIRTHDATE_NAME, "1940-01-01");
+ checkAttributeInSession(session, PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, "http://eidas.europa.eu/LoA/high");
+ checkAttributeInSession(session, PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, "AT");
+
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_TYPE_NAME, "GeneralvollmachtBilateral");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, "Gerti");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, "Musterfrau");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, "01-02-1941");
+ checkAttributeInSession(session, PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, "AT+XX:AFSDAFSDFDSFCSDAFASDF=");
+
+
+ //pre-generated eIDAS identifer
+ checkAttributeInSession(session, MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER,
+ "QVGm48cqcM4UcyhDTNGYmVdrIoY=");
+
+
+ }
+
private void checkAttributeInSession(AuthProcessDataWrapper session, String attrName, String expected) {
String value = session.getGenericDataFromSession(attrName, String.class);
Assert.assertEquals("wrong attr. value", expected, value);
diff --git a/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/RequestIdAustriaSystemTaskTest.java b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/RequestIdAustriaSystemTaskTest.java
index e5493332..6dc8d415 100644
--- a/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/RequestIdAustriaSystemTaskTest.java
+++ b/eidas_modules/authmodule_id-austria/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/task/RequestIdAustriaSystemTaskTest.java
@@ -1,12 +1,14 @@
package at.asitplus.eidas.specific.modules.auth.idaustria.test.task;
import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Base64;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -45,6 +47,7 @@ import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
import at.gv.egiz.eaaf.core.impl.idp.module.gui.DummyGuiBuilderConfigurationFactory;
import at.gv.egiz.eaaf.core.impl.idp.process.ExecutionContextImpl;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
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.Pvp2InternalErrorException;
@@ -290,6 +293,48 @@ public class RequestIdAustriaSystemTaskTest {
}
+ @Test
+ public void successWithMandates() throws Pvp2InternalErrorException, SecurityException, Exception {
+ metadataProvider.addMetadataResolverIntoChain(
+ metadataFactory.createMetadataProvider(METADATA_PATH, null, "jUnitTest", null));
+
+ LightRequest.Builder eidasRequestBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spType("public")
+ .requesterId(RandomStringUtils.randomAlphanumeric(10))
+ .providerName(RandomStringUtils.randomAlphanumeric(10));
+ LightRequest eidasReq = eidasRequestBuilder.build();
+ pendingReq.setEidasRequest(eidasReq);
+
+ List<String> mandateProfiles = Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ oaParam.setMandateProfiles(mandateProfiles);
+
+ //execute test
+ task.execute(pendingReq, executionContext);
+
+ //validate state
+ final EaafRequestedAttributes reqAttr = validate();
+ Assert.assertEquals("#Req Attribute", 6, reqAttr.getAttributes().size());
+
+ Assert.assertEquals("Wrong req attr.", "urn:eidgvat:attributes.ServiceProviderMandateProfiles",
+ reqAttr.getAttributes().get(5).getName());
+ Assert.assertNotNull("Req. Attr value element", reqAttr.getAttributes().get(1).getAttributeValues());
+ Assert.assertEquals("#Req. Attr value", 1,
+ reqAttr.getAttributes().get(5).getAttributeValues().size());
+ org.springframework.util.Assert.isInstanceOf(XSString.class,
+ reqAttr.getAttributes().get(5).getAttributeValues().get(0), "Wrong requested Attributes Value type");
+
+ List<String> reqProfiles = KeyValueUtils.getListOfCsvValues(
+ ((XSString)reqAttr.getAttributes().get(5).getAttributeValues().get(0)).getValue());
+ reqProfiles.stream().forEach(el -> assertTrue("missing profile: " + el, mandateProfiles.contains(el)));
+
+ }
+
private EaafRequestedAttributes validate() throws Pvp2InternalErrorException, SecurityException, Exception {
Assert.assertEquals("HTTP Statuscode", 200, httpResp.getStatus());
Assert.assertEquals("ContentType", "text/html;charset=UTF-8", httpResp.getContentType());
diff --git a/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_jur.xml b/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_jur.xml
new file mode 100644
index 00000000..da97bbf4
--- /dev/null
+++ b/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_jur.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" 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">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_602c3236bffaf71ac3ac88674e76ff9f" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0">
+ <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp/metadata</saml2:Issuer>
+ <saml2:Subject>
+ <saml2:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" NameQualifier="urn:publicid:gv.at:cdid+BF">QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:NameID>
+ <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
+ <saml2:SubjectConfirmationData InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" NotOnOrAfter="2014-03-05T06:44:51.017Z" Recipient="https://localhost/authhandler/sp/eidas/post"/>
+ </saml2:SubjectConfirmation>
+ </saml2:Subject>
+ <saml2:Conditions NotBefore="2014-03-05T06:39:51.017Z" NotOnOrAfter="2035-03-05T06:44:51.017Z">
+ <saml2:AudienceRestriction>
+ <saml2:Audience>https://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</saml2:AuthnContextClassRef>
+ </saml2:AuthnContext>
+ </saml2:AuthnStatement>
+ <saml2:AttributeStatement>
+ <saml2:Attribute FriendlyName="PVP-VERSION" Name="urn:oid:1.2.40.0.10.2.1.1.261.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">2.1</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="EID-CITIZEN-QAA- EIDAS-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.108" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/high</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="EID-ISSUING-NATION" Name="urn:oid:1.2.40.0.10.2.1.1.261.32" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">AT</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="PRINCIPAL-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.20" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Mustermann</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Max</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="BIRTHDATE" Name="urn:oid:1.2.40.0.10.2.1.1.55" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1940-01-01</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="BPK" Name="urn:oid:1.2.40.0.10.2.1.1.149" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">AT+XX:QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:AttributeValue>
+ </saml2:Attribute>
+
+ <saml2:Attribute 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:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Generalvollmacht</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute 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:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">999999m</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute 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:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">urn:publicid:gv.at:baseid+XERSB</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute 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:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Testfirma</saml2:AttributeValue>
+ </saml2:Attribute>
+
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_nat.xml b/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_nat.xml
new file mode 100644
index 00000000..8a84503d
--- /dev/null
+++ b/eidas_modules/authmodule_id-austria/src/test/resources/data/Response_with_EID_with_mandate_nat.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://localhost/authhandler/sp/idaustria/eidas/post" 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">classpath:/data/idp_metadata_classpath_entity.xml</saml2:Issuer>
+ <saml2p:Status>
+ <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </saml2p:Status>
+ <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_602c3236bffaf71ac3ac88674e76ff9f" IssueInstant="2014-03-05T06:39:51.017Z" Version="2.0">
+ <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://demo.egiz.gv.at/demoportal_moaid-2.0/pvp/metadata</saml2:Issuer>
+ <saml2:Subject>
+ <saml2:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" NameQualifier="urn:publicid:gv.at:cdid+BF">QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:NameID>
+ <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
+ <saml2:SubjectConfirmationData InResponseTo="_aeebfae3ce681fe3ddcaf213a42f01d3" NotOnOrAfter="2014-03-05T06:44:51.017Z" Recipient="https://localhost/authhandler/sp/eidas/post"/>
+ </saml2:SubjectConfirmation>
+ </saml2:Subject>
+ <saml2:Conditions NotBefore="2014-03-05T06:39:51.017Z" NotOnOrAfter="2035-03-05T06:44:51.017Z">
+ <saml2:AudienceRestriction>
+ <saml2:Audience>https://localhost/authhandler/sp/idaustria/eidas/metadata</saml2:Audience>
+ </saml2:AudienceRestriction>
+ </saml2:Conditions>
+ <saml2:AuthnStatement AuthnInstant="2014-03-05T06:39:51.017Z" SessionIndex="_c0c683509a8ff6ac372a9cf9c5c5a406">
+ <saml2:AuthnContext>
+ <saml2:AuthnContextClassRef>http://eidas.europa.eu/LoA/high</saml2:AuthnContextClassRef>
+ </saml2:AuthnContext>
+ </saml2:AuthnStatement>
+ <saml2:AttributeStatement>
+ <saml2:Attribute FriendlyName="PVP-VERSION" Name="urn:oid:1.2.40.0.10.2.1.1.261.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">2.1</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="EID-CITIZEN-QAA- EIDAS-LEVEL" Name="urn:oid:1.2.40.0.10.2.1.1.261.108" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">http://eidas.europa.eu/LoA/high</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="EID-ISSUING-NATION" Name="urn:oid:1.2.40.0.10.2.1.1.261.32" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">AT</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="PRINCIPAL-NAME" Name="urn:oid:1.2.40.0.10.2.1.1.261.20" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Mustermann</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="GIVEN-NAME" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Max</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="BIRTHDATE" Name="urn:oid:1.2.40.0.10.2.1.1.55" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1940-01-01</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute FriendlyName="BPK" Name="urn:oid:1.2.40.0.10.2.1.1.149" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">AT+XX:QVGm48cqcM4UcyhDTNGYmVdrIoY=</saml2:AttributeValue>
+ </saml2:Attribute>
+
+ <saml2:Attribute 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:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">GeneralvollmachtBilateral</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute 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:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">AT+XX:AFSDAFSDFDSFCSDAFASDF=</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute 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:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Gerti</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute 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:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Musterfrau</saml2:AttributeValue>
+ </saml2:Attribute>
+ <saml2:Attribute 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:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">01-02-1941</saml2:AttributeValue>
+ </saml2:Attribute>
+
+ </saml2:AttributeStatement>
+ </saml2:Assertion>
+</saml2p:Response>
diff --git a/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java b/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java
index e5d4d33e..336e6c05 100644
--- a/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java
+++ b/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java
@@ -18,12 +18,26 @@ public class MsProxyServiceConstants {
public static final String ATTR_EIDAS_PERSONAL_IDENTIFIER =
AbstractAuthenticationDataBuilder.GENERIC_AUTHDATA_IDENTIFIER + PvpAttributeDefinitions.BPK_NAME;
+ public static final String ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER =
+ AbstractAuthenticationDataBuilder.GENERIC_AUTHDATA_IDENTIFIER + PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME;
+ public static final String ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER =
+ AbstractAuthenticationDataBuilder.GENERIC_AUTHDATA_IDENTIFIER
+ + PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME;
+
//configuration constants
public static final String CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID = Constants.CONIG_PROPS_EIDAS_NODE
+ ".proxy.entityId";
public static final String CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL = Constants.CONIG_PROPS_EIDAS_NODE
+ ".proxy.forward.endpoint";
-
+
+ // mandate configuration
+ public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED = Constants.CONIG_PROPS_EIDAS_PREFIX
+ + ".proxy.mandates.enabled";
+ public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT = Constants.CONIG_PROPS_EIDAS_PREFIX
+ + ".proxy.mandates.profiles.default";
+ public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_SPECIFIC = Constants.CONIG_PROPS_EIDAS_PREFIX
+ + ".proxy.mandates.profiles.specific.";
+
//http end-points
public static final String EIDAS_HTTP_ENDPOINT_IDP_POST = "/eidas/light/idp/post";
diff --git a/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java b/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java
index aafe57e7..8e417c36 100644
--- a/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java
+++ b/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java
@@ -2,7 +2,9 @@ package at.asitplus.eidas.specific.modules.msproxyservice.protocol;
import java.io.IOException;
import java.text.MessageFormat;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -30,6 +32,7 @@ import at.gv.egiz.eaaf.core.api.idp.IModulInfo;
import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractController;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
import eu.eidas.auth.commons.EidasParameterKeys;
import eu.eidas.auth.commons.light.ILightRequest;
import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames;
@@ -221,7 +224,10 @@ public class EidasProxyServiceController extends AbstractController implements I
EaafConstants.URN_PREFIX_EIDAS + ccCountry + "+" + spCountry);
spConfig.setRequiredLoA(
eidasRequest.getLevelsOfAssurance().stream().map(el -> el.getValue()).collect(Collectors.toList()));
-
+
+ spConfig.setMandateProfiles(buildMandateProfileConfiguration(eidasRequest));
+
+
return spConfig;
} catch (EaafException e) {
@@ -230,4 +236,28 @@ public class EidasProxyServiceController extends AbstractController implements I
}
}
+ private List<String> buildMandateProfileConfiguration(ILightRequest eidasRequest) {
+ if (authConfig.getBasicConfigurationBoolean(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, false)) {
+ log.trace("eIDAS Proxy-Service allows mandates. Selecting profiles ... ");
+ List<String> spMandateProfiles = authConfig.getBasicConfigurationWithPrefix(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_SPECIFIC)
+ .entrySet().stream()
+ .filter(el -> el.getKey().endsWith(eidasRequest.getSpCountryCode().toLowerCase()))
+ .findFirst()
+ .map(el -> KeyValueUtils.getListOfCsvValues(el.getValue()))
+ .orElse(KeyValueUtils.getListOfCsvValues(
+ authConfig.getBasicConfiguration(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT)));
+
+ log.debug("Set mandate-profiles: {} to request from country: {}",
+ spMandateProfiles, eidasRequest.getSpCountryCode());
+ return spMandateProfiles;
+
+ }
+
+ return Collections.emptyList();
+
+ }
+
}
diff --git a/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java b/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java
index c51db460..9de2eb79 100644
--- a/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java
+++ b/eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java
@@ -21,10 +21,12 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRe
import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants;
import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException;
import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
import at.gv.egiz.eaaf.core.api.gui.ISpringMvcGuiFormBuilder;
import at.gv.egiz.eaaf.core.api.idp.IAction;
import at.gv.egiz.eaaf.core.api.idp.IAuthData;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.IEidAuthData;
import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface;
import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
@@ -143,6 +145,80 @@ public class ProxyServiceAuthenticationAction implements IAction {
private ImmutableAttributeMap buildAttributesFromAuthData(IAuthData authData) {
+ IEidAuthData eidAuthData = (IEidAuthData) authData;
+ if (eidAuthData.isUseMandate()) {
+ log.debug("Building eIDAS Proxy-Service response with mandate ... ");
+ final ImmutableAttributeMap.Builder attributeMap = ImmutableAttributeMap.builder();
+ injectRepesentativeInformation(attributeMap, eidAuthData);
+ injectMandatorInformation(attributeMap, eidAuthData);
+ return attributeMap.build();
+
+ } else {
+ log.debug("Building eIDAS Proxy-Service response without mandates ... ");
+ return buildAttributesWithoutMandate(eidAuthData);
+
+ }
+ }
+
+ private void injectMandatorInformation(
+ ImmutableAttributeMap.Builder attributeMap, IEidAuthData eidAuthData) {
+ String natMandatorId = eidAuthData.getGenericData(
+ MsProxyServiceConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER, String.class);
+
+ if (StringUtils.isNotEmpty(natMandatorId)) {
+ log.debug("Injecting natural mandator informations ... ");
+ final AttributeDefinition<?> attrDefPersonalId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
+ final AttributeDefinition<?> attrDefFamilyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_CURRENTFAMILYNAME).first();
+ final AttributeDefinition<?> attrDefGivenName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_CURRENTGIVENNAME).first();
+ final AttributeDefinition<?> attrDefDateOfBirth = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_DATEOFBIRTH).first();
+
+ attributeMap.put(attrDefPersonalId, natMandatorId);
+ attributeMap.put(attrDefFamilyName, eidAuthData.getGenericData(
+ PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, String.class));
+ attributeMap.put(attrDefGivenName, eidAuthData.getGenericData(
+ PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, String.class));
+ attributeMap.put(attrDefDateOfBirth, eidAuthData.getGenericData(
+ PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, String.class));
+
+ } else {
+ log.debug("Injecting legal mandator informations ... ");
+ final AttributeDefinition<?> commonName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_LEGALNAME).first();
+ final AttributeDefinition<?> legalPersonId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first();
+
+ attributeMap.put(commonName, eidAuthData.getGenericData(
+ PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, String.class));
+ attributeMap.put(legalPersonId, eidAuthData.getGenericData(
+ MsProxyServiceConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER, String.class));
+
+ }
+ }
+
+ private void injectRepesentativeInformation(
+ ImmutableAttributeMap.Builder attributeMap, IEidAuthData eidAuthData) {
+ final AttributeDefinition<?> attrDefPersonalId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER).first();
+ final AttributeDefinition<?> attrDefFamilyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME).first();
+ final AttributeDefinition<?> attrDefGivenName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME).first();
+ final AttributeDefinition<?> attrDefDateOfBirth = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH).first();
+
+ attributeMap.put(attrDefPersonalId,
+ eidAuthData.getGenericData(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, String.class));
+ attributeMap.put(attrDefFamilyName, eidAuthData.getFamilyName());
+ attributeMap.put(attrDefGivenName, eidAuthData.getGivenName());
+ attributeMap.put(attrDefDateOfBirth, eidAuthData.getFormatedDateOfBirth());
+
+ }
+
+ private ImmutableAttributeMap buildAttributesWithoutMandate(IEidAuthData eidAuthData) {
final AttributeDefinition<?> attrDefPersonalId = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first();
final AttributeDefinition<?> attrDefFamilyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
@@ -153,16 +229,17 @@ public class ProxyServiceAuthenticationAction implements IAction {
Constants.eIDAS_ATTR_DATEOFBIRTH).first();
final ImmutableAttributeMap.Builder attributeMap =
- ImmutableAttributeMap.builder().put(attrDefPersonalId,
- authData.getGenericData(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, String.class))
- .put(attrDefFamilyName, authData.getFamilyName())
- .put(attrDefGivenName, authData.getGivenName())
- .put(attrDefDateOfBirth, authData.getFormatedDateOfBirth());
+ ImmutableAttributeMap.builder()
+ .put(attrDefPersonalId,
+ eidAuthData.getGenericData(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER, String.class))
+ .put(attrDefFamilyName, eidAuthData.getFamilyName())
+ .put(attrDefGivenName, eidAuthData.getGivenName())
+ .put(attrDefDateOfBirth, eidAuthData.getFormatedDateOfBirth());
return attributeMap.build();
}
-
+
private BinaryLightToken putResponseInCommunicationCache(ILightResponse lightResponse)
throws ServletException {
final BinaryLightToken binaryLightToken;
diff --git a/eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java b/eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java
index 9ce7115a..1a19b723 100644
--- a/eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java
+++ b/eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java
@@ -1,13 +1,20 @@
package at.asitplus.eidas.specific.modules.auth.idaustria.test.protocol;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.net.URISyntaxException;
import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.List;
import java.util.UUID;
import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -23,6 +30,7 @@ import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import at.asitplus.eidas.specific.connector.config.ServiceProviderConfiguration;
+import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummyConfigMap;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.CreateIdentityLinkTask;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.test.dummy.DummySpecificCommunicationService;
import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants;
@@ -51,6 +59,8 @@ public class EidasProxyServiceControllerTest {
@Autowired private DummySpecificCommunicationService proxyService;
@Autowired private DummyProtocolAuthService authService;
+ @Autowired MsConnectorDummyConfigMap config;
+
private MockHttpServletRequest httpReq;
private MockHttpServletResponse httpResp;
@@ -167,6 +177,91 @@ public class EidasProxyServiceControllerTest {
EaafConstants.URN_PREFIX_EIDAS + "AT+" + spCountryCode,
spConfig.getAreaSpecificTargetIdentifier());
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+
}
+ @Test
+ public void validAuthnRequestWithMandatesDefaultProfiles() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public");
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+ List<String> mandateProfiles =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT,
+ StringUtils.join(mandateProfiles, ","));
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("mandateprofile size", mandateProfiles.size(), spConfig.getMandateProfiles().size());
+ spConfig.getMandateProfiles().stream()
+ .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfiles.contains(el)));
+
+ }
+
+ @Test
+ public void validAuthnRequestWithMandatesCountryProfiles() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(spCountryCode)
+ .spType("public");
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+ List<String> mandateProfiles =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ List<String> mandateProfilesCc1 =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ List<String> mandateProfilesCc2 =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT,
+ StringUtils.join(mandateProfiles, ","));
+
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_SPECIFIC
+ + RandomStringUtils.randomAlphabetic(2).toLowerCase(),
+ StringUtils.join(mandateProfilesCc1, ","));
+ config.putConfigValue(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_SPECIFIC + spCountryCode.toLowerCase(),
+ StringUtils.join(mandateProfilesCc2, ","));
+
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
+
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("mandateprofile size", mandateProfiles.size(), spConfig.getMandateProfiles().size());
+ spConfig.getMandateProfiles().stream()
+ .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfilesCc2.contains(el)));
+
+ }
+
}
diff --git a/eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java b/eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java
index 96429d71..3236bbf0 100644
--- a/eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java
+++ b/eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/ProxyServiceAuthenticationActionTest.java
@@ -1,9 +1,14 @@
package at.asitplus.eidas.specific.modules.auth.idaustria.test.protocol;
import static at.asitplus.eidas.specific.connector.MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
import java.net.URISyntaxException;
+import java.net.URLDecoder;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
@@ -12,10 +17,12 @@ import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang3.RandomStringUtils;
+import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.opensaml.saml.saml2.core.NameIDType;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@@ -26,20 +33,33 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
+import com.google.common.collect.ImmutableSortedSet;
+
import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummyConfigMap;
import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummySpConfiguration;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.CreateIdentityLinkTask;
import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants;
import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServiceAuthenticationAction;
import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest;
import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions.EidIdentityStatusLevelValues;
import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IEidAuthData;
import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
import at.gv.egiz.eaaf.core.api.idp.slo.SloInformationInterface;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;
+import eu.eidas.auth.commons.attribute.AttributeDefinition;
+import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
+import eu.eidas.auth.commons.light.ILightResponse;
import eu.eidas.auth.commons.light.impl.LightRequest;
+import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames;
+import eu.eidas.specificcommunication.exception.SpecificCommunicationException;
+import eu.eidas.specificcommunication.protocol.SpecificCommunicationService;
@RunWith(SpringJUnit4ClassRunner.class)
@PrepareForTest(CreateIdentityLinkTask.class)
@@ -52,11 +72,13 @@ public class ProxyServiceAuthenticationActionTest {
@Autowired private MsConnectorDummyConfigMap basicConfig;
@Autowired private ProxyServiceAuthenticationAction action;
@Autowired private ApplicationContext context;
+ @Autowired EidasAttributeRegistry attrRegistry;
private MockHttpServletRequest httpReq;
private MockHttpServletResponse httpResp;
private ProxyServicePendingRequest pendingReq;
private MsConnectorDummySpConfiguration oaParam;
+ private SpecificCommunicationService springManagedSpecificConnectorCommunicationService;
/**
@@ -95,6 +117,12 @@ public class ProxyServiceAuthenticationActionTest {
.providerName(RandomStringUtils.randomAlphanumeric(10));
pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+ springManagedSpecificConnectorCommunicationService =
+ (SpecificCommunicationService) context.getBean(
+ SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE
+ .toString());
+
}
@Test
@@ -114,7 +142,7 @@ public class ProxyServiceAuthenticationActionTest {
attr.put(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER,
"AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
- RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18");
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false);
basicConfig.removeConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint");
EaafException exception = assertThrows(EaafException.class,
@@ -124,12 +152,86 @@ public class ProxyServiceAuthenticationActionTest {
}
@Test
- public void dummyResponseActionTest() throws EaafException {
+ public void responseWithoutMandate() throws EaafException, SpecificCommunicationException {
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", false);
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 4, respAttr.size());
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ (String) attr.get(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER));
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTFAMILYNAME, authData.getFamilyName());
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTGIVENNAME, authData.getGivenName());
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_DATEOFBIRTH,
+ authData.getFormatedDateOfBirth());
+
+ }
+
+ @Test
+ public void responseWithNatMandate() throws EaafException, SpecificCommunicationException {
+ Map<String, Object> attr = new HashMap<>();
+ attr.put(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER,
+ "AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
+
+ attr.put(MsProxyServiceConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME,
+ "1985-11-15");
+
+
+ IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true);
+
+ //perform test
+ SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
+
+ //validate state
+ Assert.assertNotNull("Result should be not null", result);
+
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 8, respAttr.size());
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER,
+ (String) attr.get(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER));
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName());
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName());
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getFormatedDateOfBirth());
+
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_PERSONALIDENTIFIER,
+ (String) attr.get(MsProxyServiceConstants.ATTR_EIDAS_NAT_MANDATOR_PERSONAL_IDENTIFIER));
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTFAMILYNAME,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME));
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_CURRENTGIVENNAME,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME));
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_DATEOFBIRTH,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME));
+
+ }
+
+ @Test
+ public void responseWithJurMandate() throws EaafException, SpecificCommunicationException {
Map<String, Object> attr = new HashMap<>();
attr.put(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER,
"AT+XX:" + RandomStringUtils.randomAlphanumeric(10));
IAuthData authData = generateDummyAuthData(attr , EaafConstants.EIDAS_LOA_HIGH,
- RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18");
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1945-04-18", true);
+
+ attr.put(MsProxyServiceConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER,
+ RandomStringUtils.randomAlphabetic(10));
+ attr.put(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME,
+ RandomStringUtils.randomAlphabetic(10));
//perform test
SloInformationInterface result = action.processRequest(pendingReq, httpReq, httpResp, authData);
@@ -137,6 +239,20 @@ public class ProxyServiceAuthenticationActionTest {
//validate state
Assert.assertNotNull("Result should be not null", result);
+ ImmutableAttributeMap respAttr = validateBasicEidasResponse(authData);
+ assertEquals("wrong attr. size", 6, respAttr.size());
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_PERSONALIDENTIFIER,
+ (String) attr.get(MsProxyServiceConstants.ATTR_EIDAS_PERSONAL_IDENTIFIER));
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTFAMILYNAME, authData.getFamilyName());
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_CURRENTGIVENNAME, authData.getGivenName());
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_REPRESENTATIVE_DATEOFBIRTH, authData.getFormatedDateOfBirth());
+
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER,
+ (String) attr.get(MsProxyServiceConstants.ATTR_EIDAS_JUR_MANDATOR_PERSONAL_IDENTIFIER));
+ checkAttrValue(respAttr, Constants.eIDAS_ATTR_LEGALNAME,
+ (String) attr.get(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME));
+
+
}
@Test
@@ -151,12 +267,50 @@ public class ProxyServiceAuthenticationActionTest {
private IAuthData generateDummyAuthData() {
return generateDummyAuthData(Collections.emptyMap(), EaafConstants.EIDAS_LOA_LOW,
- RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1940-01-01");
+ RandomStringUtils.randomAlphanumeric(10), RandomStringUtils.randomAlphanumeric(10), "1940-01-01", false);
}
- private IAuthData generateDummyAuthData(Map<String, Object> attrs, String loa, String familyName, String givenName, String dateOfBirth) {
- return new IAuthData() {
+ private void checkAttrValue(ImmutableAttributeMap respAttr, String attrName, String expected) {
+ final AttributeDefinition<?> attrDef =
+ attrRegistry.getCoreAttributeRegistry().getByFriendlyName(attrName).first();
+ Object value = respAttr.getFirstValue(attrDef);
+ assertNotNull("not attr value: " + attrName, value);
+
+ if (value instanceof String) {
+ assertEquals("wrong attr. value: " + attrName, expected, value);
+
+ } else if ( value instanceof DateTime) {
+ assertEquals("wrong attr. value: " + attrName, expected, ((DateTime)value).toString("yyyy-MM-dd"));
+
+ }
+
+ }
+
+ private ImmutableAttributeMap validateBasicEidasResponse(IAuthData authData) throws SpecificCommunicationException {
+ assertNotNull("not redirct Header", httpResp.getHeader("Location"));
+ assertTrue("wrong redirect URL", httpResp.getHeader("Location").startsWith("http://eidas.proxy/endpoint?token="));
+ String token = httpResp.getHeader("Location").substring("http://eidas.proxy/endpoint?token=".length());
+
+ ILightResponse resp = springManagedSpecificConnectorCommunicationService.getAndRemoveResponse(URLDecoder.decode(token),
+ ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes()));
+
+ assertNotNull("responseId", resp.getId());
+ assertEquals("inResponseTo", pendingReq.getEidasRequest().getId(), resp.getInResponseToId());
+ assertEquals("relayState", pendingReq.getEidasRequest().getRelayState(), resp.getRelayState());
+ assertEquals("LoA", authData.getEidasQaaLevel(), resp.getLevelOfAssurance());
+
+ assertNotNull("subjectNameId", resp.getSubject());
+ assertEquals("subjectNameIdFormat", NameIDType.TRANSIENT, resp.getSubjectNameIdFormat());
+
+ assertFalse("not attributes", resp.getAttributes().isEmpty());
+ return resp.getAttributes();
+
+ }
+
+ private IAuthData generateDummyAuthData(Map<String, Object> attrs, String loa, String familyName, String givenName, String dateOfBirth,
+ boolean useMandates) {
+ return new IEidAuthData() {
@Override
public boolean isSsoSession() {
@@ -303,6 +457,36 @@ public class ProxyServiceAuthenticationActionTest {
// TODO Auto-generated method stub
return null;
}
+
+ @Override
+ public byte[] getSignerCertificate() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public byte[] getEidToken() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public EidIdentityStatusLevelValues getEidStatus() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getVdaEndPointUrl() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean isUseMandate() {
+ return useMandates;
+
+ }
};
}