aboutsummaryrefslogtreecommitdiff
path: root/eidas_modules/eidas_proxy-sevice
diff options
context:
space:
mode:
authorThomas <>2021-05-24 14:49:48 +0200
committerThomas <>2022-03-03 16:31:56 +0100
commita2eba5646b5b43d549993859849cdcf2baae5eb2 (patch)
treeb6815e24f56f09a9b01101c179cb0f231f2914f2 /eidas_modules/eidas_proxy-sevice
parent45b0a790ad412e6b7118f1c937b620c66a32fd64 (diff)
downloadNational_eIDAS_Gateway-a2eba5646b5b43d549993859849cdcf2baae5eb2.tar.gz
National_eIDAS_Gateway-a2eba5646b5b43d549993859849cdcf2baae5eb2.tar.bz2
National_eIDAS_Gateway-a2eba5646b5b43d549993859849cdcf2baae5eb2.zip
select mandate based on eIDAS Proxy-Service request information
Diffstat (limited to 'eidas_modules/eidas_proxy-sevice')
-rw-r--r--eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/MsProxyServiceConstants.java25
-rw-r--r--eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java253
-rw-r--r--eidas_modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/ProxyServiceAuthenticationAction.java113
-rw-r--r--eidas_modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties9
-rw-r--r--eidas_modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/auth/idaustria/test/protocol/EidasProxyServiceControllerTest.java416
5 files changed, 682 insertions, 134 deletions
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 336e6c05..72890bad 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
@@ -1,6 +1,7 @@
package at.asitplus.eidas.specific.modules.msproxyservice;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
+import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;
import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
import at.gv.egiz.eaaf.core.impl.idp.auth.builder.AbstractAuthenticationDataBuilder;
@@ -12,7 +13,7 @@ import at.gv.egiz.eaaf.core.impl.idp.auth.builder.AbstractAuthenticationDataBuil
*/
public class MsProxyServiceConstants {
- //general constants
+ // general constants
public static final String TEMPLATE_SP_UNIQUE_ID = "eidasProxyAuth_from_{0}_type_{1}";
public static final String ATTR_EIDAS_PERSONAL_IDENTIFIER =
@@ -24,19 +25,27 @@ public class MsProxyServiceConstants {
AbstractAuthenticationDataBuilder.GENERIC_AUTHDATA_IDENTIFIER
+ PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME;
- //configuration constants
+ // 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.";
+ 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_NATURAL =
+ Constants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.profiles.natural.default";
+ public static final String CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL =
+ Constants.CONIG_PROPS_EIDAS_PREFIX + ".proxy.mandates.profiles.legal.default";
+
+ // specifuc eIDAS-Connector configuration
+ public static final String CONIG_PROPS_CONNECTOR_PREFIX = "connector";
+ public static final String CONIG_PROPS_CONNECTOR_UNIQUEID = EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER;
+ public static final String CONIG_PROPS_CONNECTOR_COUNTRYCODE = "countryCode";
+ public static final String CONIG_PROPS_CONNECTOR_MANDATES_ENABLED = "mandates.enabled";
+ public static final String CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL = "mandates.natural";
+ public static final String CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL = "mandates.legal";
//http end-points
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 fda1652e..4b699bae 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
@@ -4,14 +4,18 @@ 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.UUID;
import java.util.stream.Collectors;
+import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
+import org.opensaml.saml.saml2.core.NameIDType;
+import org.opensaml.saml.saml2.core.StatusCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -19,6 +23,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import com.google.common.collect.ImmutableSortedSet;
+import at.asitplus.eidas.specific.connector.MsEidasNodeConstants;
import at.asitplus.eidas.specific.connector.config.ServiceProviderConfiguration;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
@@ -28,13 +33,18 @@ import at.gv.egiz.components.eventlog.api.EventConstants;
import at.gv.egiz.eaaf.core.api.IRequest;
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.ExtendedPvpAttributeDefinitions.SpMandateModes;
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.exceptions.GuiBuildException;
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.auth.commons.light.impl.LightResponse;
+import eu.eidas.auth.commons.light.impl.LightResponse.Builder;
+import eu.eidas.auth.commons.light.impl.ResponseStatus;
import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames;
import eu.eidas.specificcommunication.exception.SpecificCommunicationException;
import eu.eidas.specificcommunication.protocol.SpecificCommunicationService;
@@ -56,11 +66,15 @@ public class EidasProxyServiceController extends AbstractController implements I
private static final String ERROR_03 = "eidas.proxyservice.03";
private static final String ERROR_04 = "eidas.proxyservice.04";
private static final String ERROR_05 = "eidas.proxyservice.05";
-
+ private static final String ERROR_07 = "eidas.proxyservice.07";
+ private static final String ERROR_08 = "eidas.proxyservice.08";
+ private static final String ERROR_09 = "eidas.proxyservice.09";
+ private static final String ERROR_10 = "eidas.proxyservice.10";
+
public static final String PROTOCOL_ID = "eidasProxy";
- @Autowired
- private EidasAttributeRegistry attrRegistry;
+ @Autowired EidasAttributeRegistry attrRegistry;
+ @Autowired ProxyServiceAuthenticationAction responseAction;
/**
* End-point that receives authentication requests from eIDAS Node.
@@ -101,7 +115,8 @@ public class EidasProxyServiceController extends AbstractController implements I
ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes()));
log.debug("Received eIDAS auth. request from: {}, Initializing authentication environment ... ",
eidasRequest.getSpCountryCode() != null ? eidasRequest.getSpCountryCode() : "'missing SP-country'");
-
+ log.trace("Received eIDAS requst: {}", eidasRequest);
+
// create pendingRequest object
pendingReq = applicationContext.getBean(ProxyServicePendingRequest.class);
pendingReq.initialize(httpReq, authConfig);
@@ -114,6 +129,10 @@ public class EidasProxyServiceController extends AbstractController implements I
pendingReq.getUniqueTransactionIdentifier(), EventConstants.TRANSACTION_IP,
httpReq.getRemoteAddr());
+
+ //TODO: map issuer from eIDAS request to countryCode in special cases
+
+
// validate eIDAS Authn. request and set into pending-request
validateEidasAuthnRequest(eidasRequest);
pendingReq.setEidasRequest(eidasRequest);
@@ -156,10 +175,43 @@ public class EidasProxyServiceController extends AbstractController implements I
}
@Override
- public boolean generateErrorMessage(Throwable e, HttpServletRequest request, HttpServletResponse response,
- IRequest protocolRequest) throws Throwable {
+ public boolean generateErrorMessage(Throwable e, HttpServletRequest httpReq, HttpServletResponse httpResp,
+ IRequest pendingReq) throws Throwable {
+ if (pendingReq instanceof ProxyServicePendingRequest) {
+ try {
+ ILightRequest eidasReq = ((ProxyServicePendingRequest) pendingReq).getEidasRequest();
+
+ //build eIDAS response
+ Builder lightRespBuilder = LightResponse.builder();
+ lightRespBuilder.id(UUID.randomUUID().toString());
+ lightRespBuilder.inResponseToId(eidasReq.getId());
+ lightRespBuilder.relayState(eidasReq.getRelayState());
+ lightRespBuilder.issuer(authConfig.getBasicConfiguration(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_ENTITYID));
+ lightRespBuilder.subject(UUID.randomUUID().toString());
+ lightRespBuilder.subjectNameIdFormat(NameIDType.TRANSIENT);
+ lightRespBuilder.status(ResponseStatus.builder()
+ .statusCode(StatusCode.RESPONDER)
+ .subStatusCode(statusMessager.mapInternalErrorToExternalError(statusMessager.getResponseErrorCode(e)))
+ .statusMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage()))
+ .build());
+
+ // forward to eIDAS Proxy-Service
+ responseAction.forwardToEidasProxy(pendingReq, httpReq, httpResp, lightRespBuilder.build());
+
+ return true;
+
+ } catch (ServletException | IOException | GuiBuildException e1) {
+ log.warn("Forward error to eIDAS Proxy-Service FAILED. Handle error localy ... ", e1);
+
+ }
+
+ } else {
+ log.error("eIDAS Proxy-Service authentication requires PendingRequest of Type: {}",
+ ProxyServicePendingRequest.class.getName());
- // TODO: implement error handling for eIDAS Node communication
+ }
+
return false;
}
@@ -189,16 +241,17 @@ public class EidasProxyServiceController extends AbstractController implements I
* @throws EidasProxyServiceException In case of a validation error
*/
private void validateEidasAuthnRequest(ILightRequest eidasRequest) throws EidasProxyServiceException {
- if (StringUtils.isEmpty(eidasRequest.getSpCountryCode())) {
+ if (StringUtils.isEmpty(eidasRequest.getIssuer())) {
throw new EidasProxyServiceException(ERROR_05, null);
}
-
- /*
- * TODO: validate requested attributes --> check if natural-person and
- * legal-person attributes requested in parallel
- */
-
+
+ // check if natural-person and legal-person attributes requested in parallel
+ if (isLegalPersonRequested(eidasRequest) && isNaturalPersonRequested(eidasRequest)) {
+ throw new EidasProxyServiceException(ERROR_08, null);
+
+ }
+
// TODO: validate some other stuff
}
@@ -213,63 +266,167 @@ public class EidasProxyServiceController extends AbstractController implements I
private ISpConfiguration generateSpConfigurationFromEidasRequest(ILightRequest eidasRequest)
throws EidasProxyServiceException {
try {
- final String spCountry = eidasRequest.getSpCountryCode();
- final Map<String, String> spConfigMap = new HashMap<>();
+
+ Map<String, String> connectorConfigMap = extractRawConnectorConfiguration(eidasRequest);
+
+ // check if country-code is available
+ String spCountry = connectorConfigMap.get(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE);
+ if (StringUtils.isEmpty(spCountry)) {
+ throw new EidasProxyServiceException(ERROR_07, null);
- // TODO: how we get the EntityId from eIDAS connector?
- spConfigMap.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER,
+ }
+
+ // build FriendyName from CountryCode and SPType
+ connectorConfigMap.put(MsEidasNodeConstants.PROP_CONFIG_SP_FRIENDLYNAME,
MessageFormat.format(MsProxyServiceConstants.TEMPLATE_SP_UNIQUE_ID,
spCountry, eidasRequest.getSpType()));
- final ServiceProviderConfiguration spConfig = new ServiceProviderConfiguration(spConfigMap, authConfig);
+ // build Service-Provider configuration object
+ final ServiceProviderConfiguration spConfig = new ServiceProviderConfiguration(connectorConfigMap, authConfig);
+ // build bPK target from Country-Code
final String ccCountry = authConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE,
Constants.DEFAULT_MS_NODE_COUNTRY_CODE);
-
spConfig.setBpkTargetIdentifier(
EaafConstants.URN_PREFIX_EIDAS + ccCountry + "+" + spCountry);
+
+ // set required LoA from eIDAS request
spConfig.setRequiredLoA(
eidasRequest.getLevelsOfAssurance().stream().map(el -> el.getValue()).collect(Collectors.toList()));
- // TODO: check if only mandates are allowed in case of legal person requested
- // --> set force-mandate flag
- spConfig.setMandateProfiles(buildMandateProfileConfiguration(eidasRequest));
-
+ //build mandate profiles for this specific request
+ buildMandateProfileConfiguration(spConfig, eidasRequest);
+
return spConfig;
+ } catch (EidasProxyServiceException e) {
+ throw e;
+
} catch (final EaafException e) {
throw new EidasProxyServiceException(ERROR_04, new Object[] { e.getMessage() }, e);
}
}
- 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 ... ");
-
- /*
- * TODO: split profiles in natural-person and legal-person profiles and select
- * correct one based on requested attributes
- */
- final 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;
+
+ private Map<String, String> extractRawConnectorConfiguration(ILightRequest eidasRequest) {
+ Map<String, String> allConnectorConfigs = authConfig.getBasicConfigurationWithPrefix(
+ MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_PREFIX);
+ if (log.isTraceEnabled()) {
+ log.trace("Full-connector configuration:");
+ allConnectorConfigs.entrySet().stream().forEach(
+ el -> log.trace("Key: {} -> Value: {}", el.getKey(), el.getValue()));
+
+ }
+
+
+ Map<String, String> connectorConfig = allConnectorConfigs.entrySet().stream()
+ .filter(el -> el.getKey().endsWith(MsEidasNodeConstants.PROP_CONFIG_SP_UNIQUEIDENTIFIER)
+ && el.getValue().equals(eidasRequest.getIssuer()))
+ .findFirst()
+ .map(el -> KeyValueUtils.getSubSetWithPrefix(allConnectorConfigs,
+ KeyValueUtils.getParentKey(el.getKey()) + KeyValueUtils.KEY_DELIMITER))
+ .orElse(new HashMap<>());
+
+
+ if (connectorConfig.isEmpty()) {
+ log.debug("No specific configuration for eIDAS Connector: {} Using default configuration ... ",
+ eidasRequest.getIssuer());
+
+ // set EntityId of the requesting eIDAS Connector
+ connectorConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, eidasRequest.getIssuer());
+
+ // set country-code from eIDAS request
+ connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE,
+ eidasRequest.getSpCountryCode());
+
+ // set default mandate configuration
+ connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED,
+ String.valueOf(authConfig.getBasicConfigurationBoolean(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, false)));
+ connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL,
+ authConfig.getBasicConfiguration(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL));
+ connectorConfig.put(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL,
+ authConfig.getBasicConfiguration(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL));
+
+ } else {
+ log.debug("Find specific configuration for eIDAS Connector: {}", eidasRequest.getIssuer());
+
+ }
+
+ return connectorConfig;
+
+ }
+
+
+ private void buildMandateProfileConfiguration(ServiceProviderConfiguration spConfig, ILightRequest eidasRequest)
+ throws EidasProxyServiceException {
+ // check if mandates are enabled
+ if (spConfig.isConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, false)) {
+ injectMandateInfosIntoSpConfig(spConfig, eidasRequest);
+
+ } else {
+ if (isLegalPersonRequested(eidasRequest)) {
+ throw new EidasProxyServiceException(ERROR_09, null);
+
+ }
+
+ spConfig.setMandateProfiles(Collections.emptyList());
+ spConfig.setMandateMode(SpMandateModes.NONE);
+
+ }
+ }
+
+ private void injectMandateInfosIntoSpConfig(ServiceProviderConfiguration spConfig,
+ ILightRequest eidasRequest) throws EidasProxyServiceException {
+ log.trace("eIDAS Proxy-Service allows mandates for Connector: {}. Selecting profiles ... ",
+ spConfig.getUniqueIdentifier());
+
+ //check if legal person is requested
+ boolean isLegalPersonRequested = isLegalPersonRequested(eidasRequest);
+
+ // set mandate profiles
+ if (isLegalPersonRequested) {
+ spConfig.setMandateProfiles(KeyValueUtils.getListOfCsvValues(
+ spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL)));
+
+ spConfig.setMandateMode(SpMandateModes.LEGAL_FORCE);
+
+ } else if (isNaturalPersonRequested(eidasRequest)) {
+ spConfig.setMandateProfiles(KeyValueUtils.getListOfCsvValues(
+ spConfig.getConfigurationValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL)));
+
+ spConfig.setMandateMode(SpMandateModes.NATURAL);
+
}
- return Collections.emptyList();
+ log.debug("Set mandate-profiles: {} to request from issuer: {}",
+ spConfig.getMandateProfiles(), spConfig.getUniqueIdentifier());
+
+ if (isLegalPersonRequested && spConfig.getMandateProfiles().isEmpty()) {
+ throw new EidasProxyServiceException(ERROR_10, null);
+
+ }
+
}
+ private boolean isLegalPersonRequested(ILightRequest eidasRequest) {
+ return eidasRequest.getRequestedAttributes().entrySet().stream()
+ .filter(el -> el.getKey().getFriendlyName().equals(Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER))
+ .findFirst()
+ .isPresent();
+
+ }
+
+ private boolean isNaturalPersonRequested(ILightRequest eidasRequest) {
+ return eidasRequest.getRequestedAttributes().entrySet().stream()
+ .filter(el -> el.getKey().getFriendlyName().equals(Constants.eIDAS_ATTR_PERSONALIDENTIFIER))
+ .findFirst()
+ .isPresent();
+
+ }
}
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 5d184cc8..805bbc42 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
@@ -96,10 +96,6 @@ public class ProxyServiceAuthenticationAction implements IAction {
lightRespBuilder.levelOfAssurance(authData.getEidasQaaLevel());
lightRespBuilder.attributes(buildAttributesFromAuthData(authData));
- // put request into shared cache
- final BinaryLightToken token = putResponseInCommunicationCache(lightRespBuilder.build());
- final String tokenBase64 = BinaryLightTokenHelper.encodeBinaryLightTokenBase64(token);
-
// set SLO response object of EAAF framework
final SloInformationImpl sloInformation = new SloInformationImpl();
sloInformation.setProtocolType(pendingReq.requestedModule());
@@ -107,7 +103,7 @@ public class ProxyServiceAuthenticationAction implements IAction {
.setSpEntityID(pendingReq.getServiceProviderConfiguration().getUniqueIdentifier());
// forward to eIDAS Proxy-Service
- forwardToEidasProxy(pendingReq, httpReq, httpResp, tokenBase64);
+ forwardToEidasProxy(pendingReq, httpReq, httpResp, lightRespBuilder.build());
return sloInformation;
@@ -136,6 +132,68 @@ public class ProxyServiceAuthenticationAction implements IAction {
}
+
+ /**
+ * Forward eIDAS Light response to eIDAS node.
+ *
+ * @param pendingReq Current pending request.
+ * @param httpReq Current HTTP request
+ * @param httpResp Current HTTP response
+ * @param lightResponse eIDAS LightResponse
+ * @throws EaafConfigurationException In case of a configuration error
+ * @throws IOException In case of a general error
+ * @throws GuiBuildException In case of a GUI rendering error, if http POST binding is used
+ * @throws ServletException In case of a general error
+ */
+ public void forwardToEidasProxy(IRequest pendingReq, HttpServletRequest httpReq,
+ HttpServletResponse httpResp, LightResponse lightResponse) throws EaafConfigurationException, IOException,
+ GuiBuildException, ServletException {
+
+ // put request into shared cache
+ final BinaryLightToken token = putResponseInCommunicationCache(lightResponse);
+ final String tokenBase64 = BinaryLightTokenHelper.encodeBinaryLightTokenBase64(token);
+
+ // select forward URL regarding the selected environment
+ final String forwardUrl = basicConfig.getBasicConfiguration(
+ MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL);
+
+ if (StringUtils.isEmpty(forwardUrl)) {
+ log.warn("NO ForwardURL defined in configuration. Can NOT forward to eIDAS node! Process stops");
+ throw new EaafConfigurationException("config.08",
+ new Object[] { MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL });
+
+ }
+ log.debug("ForwardURL: " + forwardUrl + " selected to forward eIDAS request");
+
+ if (basicConfig.getBasicConfiguration(
+ Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD,
+ Constants.FORWARD_METHOD_GET).equals(Constants.FORWARD_METHOD_GET)) {
+
+ log.debug("Use http-redirect for eIDAS node forwarding ... ");
+ // send redirect
+ final UriComponentsBuilder redirectUrl = UriComponentsBuilder.fromHttpUrl(forwardUrl);
+ redirectUrl.queryParam(EidasParameterKeys.TOKEN.toString(), tokenBase64);
+ httpResp.sendRedirect(redirectUrl.build().encode().toString());
+
+ } else {
+ log.debug("Use http-post for eIDAS node forwarding ... ");
+ final StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration(
+ basicConfig,
+ pendingReq,
+ Constants.TEMPLATE_POST_FORWARD_NAME,
+ null,
+ resourceLoader);
+
+ config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_ENDPOINT, forwardUrl);
+ config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_TOKEN_NAME,
+ EidasParameterKeys.TOKEN.toString());
+ config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_TOKEN_VALUE,
+ tokenBase64);
+
+ guiBuilder.build(httpReq, httpResp, config, "Forward to eIDASNode form");
+
+ }
+ }
@PostConstruct
private void checkConfiguration() {
@@ -264,50 +322,5 @@ public class ProxyServiceAuthenticationAction implements IAction {
return binaryLightToken;
}
- private void forwardToEidasProxy(IRequest pendingReq, HttpServletRequest httpReq,
- HttpServletResponse httpResp, String tokenBase64) throws EaafConfigurationException, IOException,
- GuiBuildException {
- // select forward URL regarding the selected environment
- final String forwardUrl = basicConfig.getBasicConfiguration(
- MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL);
-
- if (StringUtils.isEmpty(forwardUrl)) {
- log.warn("NO ForwardURL defined in configuration. Can NOT forward to eIDAS node! Process stops");
- throw new EaafConfigurationException("config.08",
- new Object[] { MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_NODE_FORWARD_URL });
-
- }
- log.debug("ForwardURL: " + forwardUrl + " selected to forward eIDAS request");
-
- if (basicConfig.getBasicConfiguration(
- Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD,
- Constants.FORWARD_METHOD_GET).equals(Constants.FORWARD_METHOD_GET)) {
-
- log.debug("Use http-redirect for eIDAS node forwarding ... ");
- // send redirect
- final UriComponentsBuilder redirectUrl = UriComponentsBuilder.fromHttpUrl(forwardUrl);
- redirectUrl.queryParam(EidasParameterKeys.TOKEN.toString(), tokenBase64);
- httpResp.sendRedirect(redirectUrl.build().encode().toString());
-
- } else {
- log.debug("Use http-post for eIDAS node forwarding ... ");
- final StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration(
- basicConfig,
- pendingReq,
- Constants.TEMPLATE_POST_FORWARD_NAME,
- null,
- resourceLoader);
-
- config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_ENDPOINT, forwardUrl);
- config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_TOKEN_NAME,
- EidasParameterKeys.TOKEN.toString());
- config.putCustomParameter(null, Constants.TEMPLATE_POST_FORWARD_TOKEN_VALUE,
- tokenBase64);
-
- guiBuilder.build(httpReq, httpResp, config, "Forward to eIDASNode form");
-
- }
-
- }
}
diff --git a/eidas_modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties b/eidas_modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties
index 5c4c51b9..b934ad56 100644
--- a/eidas_modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties
+++ b/eidas_modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties
@@ -1,8 +1,13 @@
-eidas.proxyservice.01=General error on request-validation from eIDAS-Node Proxy-Service
+eidas.proxyservice.01=General error on request-validation from national eIDAS Proxy-Service
eidas.proxyservice.02=Authentication request contains not communication token.
eidas.proxyservice.03=General error during eIDAS-Node communication. Reason: {}
eidas.proxyservice.04=Validation of eIDAS Authn request failed. Reason: {}
-eidas.proxyservice.05=No Service-Provider country-code in Authn. request. Authentication not possible
+eidas.proxyservice.05=No eIDAS-Connector Issuer in Authn. request. Authentication not possible
eidas.proxyservice.06=Can not build eIDAS Proxy-Service response. Authentication FAILED.
+eidas.proxyservice.07=Can not determine eIDAS-Connector CountryCode. Authentication not possible
+eidas.proxyservice.08=Validation of eIDAS Authn request failed. Reason: Legal person and natural person can not be requested at once.
+eidas.proxyservice.09=eIDAS authentication not possible, because legal person is requested but mandates are disabled in general
+eidas.proxyservice.10=eIDAS authentication not possible, because legal person is requested but not mandate profiles are defined
+
eidas.proxyservice.99=Internal error during eIDAS Proxy-Service authentication \ No newline at end of file
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 1a19b723..86357123 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
@@ -8,6 +8,7 @@ import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.net.URISyntaxException;
+import java.net.URLDecoder;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
@@ -19,8 +20,11 @@ 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.opensaml.saml.saml2.core.StatusCode;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
@@ -29,8 +33,12 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import com.google.common.collect.ImmutableSortedSet;
+
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.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.auth.eidas.v2.test.dummy.DummySpecificCommunicationService;
import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants;
@@ -38,12 +46,17 @@ import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxySer
import at.asitplus.eidas.specific.modules.msproxyservice.protocol.EidasProxyServiceController;
import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest;
import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
import at.gv.egiz.eaaf.core.impl.idp.module.test.DummyProtocolAuthService;
import eu.eidas.auth.commons.EidasParameterKeys;
+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)
@@ -58,12 +71,16 @@ public class EidasProxyServiceControllerTest {
@Autowired private DummySpecificCommunicationService proxyService;
@Autowired private DummyProtocolAuthService authService;
+ @Autowired private EidasAttributeRegistry attrRegistry;
+ @Autowired private ApplicationContext context;
@Autowired MsConnectorDummyConfigMap config;
private MockHttpServletRequest httpReq;
private MockHttpServletResponse httpResp;
+ private SpecificCommunicationService springManagedSpecificConnectorCommunicationService;
+
/**
* jUnit test set-up.
*/
@@ -76,7 +93,68 @@ public class EidasProxyServiceControllerTest {
proxyService.setiLightRequest(null);
proxyService.setError(null);
-
+
+ config.putConfigValue("eidas.ms.auth.eIDAS.node_v2.proxy.forward.endpoint",
+ "http://eidas.proxy/endpoint");
+
+ springManagedSpecificConnectorCommunicationService =
+ (SpecificCommunicationService) context.getBean(
+ SpecificCommunicationDefinitionBeanNames.SPECIFIC_PROXYSERVICE_COMMUNICATION_SERVICE
+ .toString());
+
+ }
+
+ @Test
+ public void generateErrorResponseWrongPendingReq() throws Throwable {
+ Assert.assertFalse("wrong statusCode", controller.generateErrorMessage(
+ new EaafException("1000"),
+ httpReq, httpResp, null));
+
+ }
+
+ @Test
+ public void generateErrorResponse() throws Throwable {
+ ProxyServicePendingRequest pendingReq = new ProxyServicePendingRequest();
+ pendingReq.initialize(httpReq, config);
+
+ 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));
+ pendingReq.setEidasRequest(eidasRequestBuilder.build());
+
+
+ // execute test
+ Assert.assertTrue("wrong statusCode", controller.generateErrorMessage(
+ new EaafException("1000"),
+ httpReq, httpResp,
+ pendingReq));
+
+ // validate state
+ 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());
+
+ assertNotNull("subjectNameId", resp.getSubject());
+ assertEquals("subjectNameIdFormat", NameIDType.TRANSIENT, resp.getSubjectNameIdFormat());
+ assertTrue("not attributes", resp.getAttributes().isEmpty());
+
+ assertEquals("StatusCode", StatusCode.RESPONDER, resp.getStatus().getStatusCode());
+ //assertEquals("SubStatusCode", "", resp.getStatus().getSubStatusCode());
+ //assertEquals("StatusMsg", "", resp.getStatus().getStatusMessage());
+
}
@Test
@@ -112,7 +190,7 @@ public class EidasProxyServiceControllerTest {
Assert.assertTrue("Wrong exception", (exception.getCause() instanceof SpecificCommunicationException));
}
-
+
@Test
public void missingServiceProviderCountry() {
//initialize state
@@ -128,11 +206,67 @@ public class EidasProxyServiceControllerTest {
//validate state
EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class,
() -> controller.receiveEidasAuthnRequest(httpReq, httpResp));
- Assert.assertEquals("wrong errorCode", "eidas.proxyservice.05", exception.getErrorId());
+ Assert.assertEquals("wrong errorCode", "eidas.proxyservice.07", exception.getErrorId());
+
+ }
+
+ @Test
+ public void requestingLegalAndNaturalPerson() {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(RandomStringUtils.randomAlphabetic(10))
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+ //validate state
+ EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class,
+ () -> controller.receiveEidasAuthnRequest(httpReq, httpResp));
+ Assert.assertEquals("wrong errorCode", "eidas.proxyservice.08", exception.getErrorId());
}
@Test
+ public void requestLegalPersonButNoMandates() 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")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+ //validate state
+ EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class,
+ () -> controller.receiveEidasAuthnRequest(httpReq, httpResp));
+ Assert.assertEquals("wrong errorCode", "eidas.proxyservice.09", exception.getErrorId());
+
+ }
+
+ @Test
public void validAuthnRequest() throws IOException, EaafException {
//initialize state
httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
@@ -143,10 +277,20 @@ public class EidasProxyServiceControllerTest {
.citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
.levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
.spCountryCode(spCountryCode)
- .spType("public");
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build());
proxyService.setiLightRequest(authnReqBuilder.build());
+
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+
//execute
controller.receiveEidasAuthnRequest(httpReq, httpResp);
@@ -168,8 +312,12 @@ public class EidasProxyServiceControllerTest {
pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class);
Assert.assertNotNull("uniqueId", spConfig.getUniqueIdentifier());
Assert.assertEquals("uniqueId wrong pattern",
+ authnReqBuilder.build().getIssuer(),
+ spConfig.getUniqueIdentifier());
+ Assert.assertEquals("friendlyName wrong pattern",
MessageFormat.format(MsProxyServiceConstants.TEMPLATE_SP_UNIQUE_ID, spCountryCode, "public"),
- spConfig.getUniqueIdentifier());
+ spConfig.getFriendlyName());
+
Assert.assertEquals("uniqueId not match to pendingReq",
pendingReq.getSpEntityId(), spConfig.getUniqueIdentifier());
Assert.assertNotNull("bpkTarget", spConfig.getAreaSpecificTargetIdentifier());
@@ -179,11 +327,12 @@ public class EidasProxyServiceControllerTest {
assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
-
+ assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode());
+
}
@Test
- public void validAuthnRequestWithMandatesDefaultProfiles() throws IOException, EaafException {
+ public void validAuthnRequestWithMandatesDefaultProfilesNat() throws IOException, EaafException {
//initialize state
httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
@@ -193,15 +342,23 @@ public class EidasProxyServiceControllerTest {
.citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
.levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
.spCountryCode(spCountryCode)
- .spType("public");
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build());
+
proxyService.setiLightRequest(authnReqBuilder.build());
- List<String> mandateProfiles =
+ List<String> mandateProfilesNat =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ List<String> mandateProfilesJur =
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_DEFAULT_NATURAL,
+ StringUtils.join(mandateProfilesNat, ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(mandateProfilesJur, ","));
//execute
controller.receiveEidasAuthnRequest(httpReq, httpResp);
@@ -211,14 +368,15 @@ public class EidasProxyServiceControllerTest {
authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
assertFalse("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
- assertEquals("mandateprofile size", mandateProfiles.size(), spConfig.getMandateProfiles().size());
+ assertEquals("mandateprofile size", mandateProfilesNat.size(), spConfig.getMandateProfiles().size());
spConfig.getMandateProfiles().stream()
- .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfiles.contains(el)));
+ .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfilesNat.contains(el)));
+ assertEquals("MandateMode", SpMandateModes.NATURAL, spConfig.getMandateMode());
}
@Test
- public void validAuthnRequestWithMandatesCountryProfiles() throws IOException, EaafException {
+ public void validAuthnRequestWithMandatesDefaultProfilesJur() throws IOException, EaafException {
//initialize state
httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
@@ -228,28 +386,168 @@ public class EidasProxyServiceControllerTest {
.citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
.levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
.spCountryCode(spCountryCode)
- .spType("public");
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build());
+
proxyService.setiLightRequest(authnReqBuilder.build());
- List<String> mandateProfiles =
+ List<String> mandateProfilesNat =
Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
- List<String> mandateProfilesCc1 =
+ List<String> mandateProfilesJur =
Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
- List<String> mandateProfilesCc2 =
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(mandateProfilesNat, ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(mandateProfilesJur, ","));
+
+ //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", mandateProfilesJur.size(), spConfig.getMandateProfiles().size());
+ spConfig.getMandateProfiles().stream()
+ .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfilesJur.contains(el)));
+ assertEquals("MandateMode", SpMandateModes.LEGAL_FORCE, spConfig.getMandateMode());
+
+ }
+
+ @Test
+ public void validAuthnRequestWithMandatesDefaultNoJurProfiles() 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")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build());
+
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+ List<String> mandateProfilesNat =
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,
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(mandateProfilesNat, ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL, "");
+
+ //validate state
+ EidasProxyServiceException exception = assertThrows(EidasProxyServiceException.class,
+ () -> controller.receiveEidasAuthnRequest(httpReq, httpResp));
+ Assert.assertEquals("wrong errorCode", "eidas.proxyservice.10", exception.getErrorId());
+
+ }
+
+ @Test
+ public void validAuthnRequestIssueSpecificNoMandates() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+
+ String issuer = RandomStringUtils.randomAlphabetic(10);
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(issuer)
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+
+ // set default mandate configuration
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+ // set specific mandate configuration
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer);
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode);
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "false");
+
+ List<String> mandateProfiles =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL,
StringUtils.join(mandateProfiles, ","));
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL,
+ StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+ //execute
+ controller.receiveEidasAuthnRequest(httpReq, httpResp);
- 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, ","));
+ //validate state
+ ServiceProviderConfiguration spConfig =
+ authService.getPendingReq().getServiceProviderConfiguration(ServiceProviderConfiguration.class);
+ assertNotNull("mandateprofiles", spConfig.getMandateProfiles());
+ assertTrue("mandateprofiles not empty", spConfig.getMandateProfiles().isEmpty());
+ assertEquals("MandateMode", SpMandateModes.NONE, spConfig.getMandateMode());
+
+ }
+
+ @Test
+ public void validAuthnRequestIssueSpecificMandatesNat() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String issuer = "https://apps.egiz.gv.at/EidasNode//ConnectorMetadata";
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(issuer)
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first()).build());
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+
+ // set default mandate configuration
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "false");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+ // set specific mandate configuration
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer);
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode);
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "true");
+
+ List<String> mandateProfiles =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL,
+ StringUtils.join(mandateProfiles, ","));
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL,
+ StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
//execute
controller.receiveEidasAuthnRequest(httpReq, httpResp);
@@ -260,8 +558,74 @@ public class EidasProxyServiceControllerTest {
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)));
+ .forEach(el -> assertTrue("missing mandateProfile: " + el, mandateProfiles.contains(el)));
+ assertEquals("MandateMode", SpMandateModes.NATURAL, spConfig.getMandateMode());
+
+ }
+
+ @Test
+ public void validAuthnRequestIssueSpecificMandatesJur() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+
+ String issuer = RandomStringUtils.randomAlphabetic(10);
+ LightRequest.Builder authnReqBuilder = LightRequest.builder()
+ .id(UUID.randomUUID().toString())
+ .issuer(issuer)
+ .citizenCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .levelOfAssurance(EaafConstants.EIDAS_LOA_HIGH)
+ .spCountryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase())
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first()).build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+
+ // set default mandate configuration
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_ENABLED, "true");
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_NATURAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(Arrays.asList(
+ RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+ // set specific mandate configuration
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_UNIQUEID, issuer);
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_COUNTRYCODE, spCountryCode);
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_ENABLED, "true");
+
+ List<String> mandateProfiles =
+ Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5));
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_LEGAL,
+ StringUtils.join(mandateProfiles, ","));
+ addConnectorConfig(0, MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_MANDATES_PROFILE_NATURAL,
+ StringUtils.join(Arrays.asList(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)), ","));
+
+ //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)));
+ assertEquals("MandateMode", SpMandateModes.LEGAL_FORCE, spConfig.getMandateMode());
+
+ }
+
+ private void addConnectorConfig(int i, String key, String value) {
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_CONNECTOR_PREFIX + String.valueOf(i) + "." + key,
+ value);
}
}
+
+