aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas <>2022-10-11 19:16:17 +0200
committerThomas <>2022-10-11 19:16:17 +0200
commit7571d90b2910740424988d0e7e5473dbd2d33cfa (patch)
tree0ec3dff2328b66831283d53448b3d5425038b2fb
parentf3f0927a1226b32d1c43a116e3421ded9c181323 (diff)
downloadNational_eIDAS_Gateway-7571d90b2910740424988d0e7e5473dbd2d33cfa.tar.gz
National_eIDAS_Gateway-7571d90b2910740424988d0e7e5473dbd2d33cfa.tar.bz2
National_eIDAS_Gateway-7571d90b2910740424988d0e7e5473dbd2d33cfa.zip
feat(ejustice): add validation to disallow eJusticeRole for legal and natural person in one single request
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java21
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java26
-rw-r--r--modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java39
-rw-r--r--modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties1
-rw-r--r--modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerBorisTest.java48
5 files changed, 132 insertions, 3 deletions
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java
index f8c14ceb..46dd714d 100644
--- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/EJusticePersonRoleHandler.java
@@ -11,12 +11,14 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException;
import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes;
import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
import at.gv.egiz.eaaf.core.api.idp.IEidAuthData;
import at.gv.egiz.eaaf.core.api.idp.IExtendedConfiguration;
import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+import eu.eidas.auth.commons.light.ILightRequest;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
@@ -31,6 +33,11 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class EJusticePersonRoleHandler implements IEidasAttributeHandler {
+ public static final String EIDAS_ATTR_EJUSTIC_NAT =
+ "http://e-justice.europa.eu/attributes/naturalperson/eJusticeNaturalPersonRole";
+ public static final String EIDAS_ATTR_EJUSTIC_JUR =
+ "http://e-justice.europa.eu/attributes/legalperson/eJusticeLegalPersonRole";
+
public static final String CONFIG_PROP_IDA_MANDATE_PROFILE = "advanced.attributes.ejusticerole.mandate.profiles";
public static final String CONFIG_PROP_IDA_MANDATE_MODE = "advanced.attributes.ejusticerole.mandate.mode";
public static final String CONFIG_PROP_IDA_ADDITIONAL_ATTRIBUTES =
@@ -140,5 +147,19 @@ public class EJusticePersonRoleHandler implements IEidasAttributeHandler {
return value;
}
+
+ @Override
+ public final void validateAuthnRequest(ILightRequest eidasRequest) throws EidasProxyServiceException {
+ boolean isNatReq =
+ eidasRequest.getRequestedAttributes().getAttributeValuesByNameUri(EIDAS_ATTR_EJUSTIC_NAT) != null;
+ boolean isJurReq =
+ eidasRequest.getRequestedAttributes().getAttributeValuesByNameUri(EIDAS_ATTR_EJUSTIC_JUR) != null;
+
+ if (isNatReq && isJurReq) {
+ log.warn("eJustice attributes for legal and natural person can NOT be requested at the same time.");
+ throw new EidasProxyServiceException("eidas.proxyservice.ejustice.01", null);
+
+ }
+ }
}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java
index 36deba30..15650e29 100644
--- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/handler/IEidasAttributeHandler.java
@@ -3,12 +3,19 @@ package at.asitplus.eidas.specific.modules.msproxyservice.handler;
import javax.annotation.Nullable;
import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException;
import at.gv.egiz.eaaf.core.api.idp.IEidAuthData;
+import eu.eidas.auth.commons.light.ILightRequest;
import lombok.NonNull;
/**
* Handlers for attribute-processing that requires more features than a simple mapping.
*
+ * <p><b>Important:</b> That interface provides attribute-specific extension- and modification hooks for
+ * post-processing of service configuration and authentication data. If more than one attribute-specific implementation
+ * operates on the same process, concurrency issues are possible because any implementation of that interface are
+ * executed independent from each other.</p>
+ *
* @author tlenz
*
*/
@@ -17,6 +24,10 @@ public interface IEidasAttributeHandler {
/**
* Perform attribute-releated post-processing of internal Service-Provider configuration.
*
+ * <p><b>Important:</b> Modifications done by that method are independent from any other implementation of
+ * the same interface and there is no specific order if more than one handler are selected. <br>
+ * Therefore, concurrency issues has to be noticed!</p>
+ *
* @param spConfig SP configuration that was build from incoming eIDAS Authn. request.
*/
void performSpConfigPostprocessing(@NonNull ServiceProviderConfiguration spConfig);
@@ -25,12 +36,18 @@ public interface IEidasAttributeHandler {
/**
* Perform attribute-specific post-processing of authentication information.
*
+ * <p><b>Important:</b> Modifications done by that method are independent from any other implementation of
+ * the same interface and there is no specific order if more than one handler are selected. <br>
+ * Therefore, concurrency issues has to be noticed!</p>
+ *
* @param authData authentication information from ID Austria system that should be post processed.
*/
@NonNull
void performAuthDataPostprocessing(@NonNull IEidAuthData authData);
+
+
/**
* Build eIDAS attribute-value from authentication data.
*
@@ -40,6 +57,15 @@ public interface IEidasAttributeHandler {
@Nullable
String buildAttributeValue(@NonNull IEidAuthData eidAuthData);
+
+ /**
+ * Extended validation of incoming eIDAS AuthnRequest.
+ *
+ * @param eidasRequest Incoming eIDAS authentication request
+ * @throws EidasProxyServiceException In case of a validation error
+ */
+ void validateAuthnRequest(ILightRequest eidasRequest) throws EidasProxyServiceException;
+
}
diff --git a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java
index d0e3d1ba..b5f6b6d2 100644
--- a/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java
+++ b/modules/eidas_proxy-sevice/src/main/java/at/asitplus/eidas/specific/modules/msproxyservice/protocol/EidasProxyServiceController.java
@@ -21,6 +21,7 @@ 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.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -264,7 +265,25 @@ public class EidasProxyServiceController extends AbstractController implements I
}
- // TODO: validate some other stuff
+ // perform advanced request validation
+ Set<String> requiredHandlers = eidasRequest.getRequestedAttributes().getAttributeMap().keySet().stream()
+ .map(el -> attrRegistry.mapEidasAttributeToAttributeHandler(el.getNameUri().toString()).orElse(null))
+ .filter(Objects::nonNull)
+ .distinct()
+ .collect(Collectors.toSet());
+
+ if (!requiredHandlers.isEmpty()) {
+ log.info("eIDAS requested attributes requires #{} specific attribute-hander. "
+ + "Starting advanced attribute-validation ... ", requiredHandlers.size());
+ for (String el : requiredHandlers) {
+ executeAdvancedRequestValidation(el, eidasRequest);
+
+ }
+
+ } else {
+ log.debug("No advanced eIDAS attribute-validation required.");
+
+ }
}
@@ -283,8 +302,8 @@ public class EidasProxyServiceController extends AbstractController implements I
&& EidasProxyServiceUtils.isNaturalPersonRequested(eidasRequest)) {
throw new EidasProxyServiceException(ERROR_08, null);
- }
-
+ }
+
// TODO: validate some other stuff
}
@@ -381,6 +400,20 @@ public class EidasProxyServiceController extends AbstractController implements I
}
}
+ private void executeAdvancedRequestValidation(String handlerClass, ILightRequest eidasRequest)
+ throws EidasProxyServiceException {
+ try {
+ IEidasAttributeHandler handler = applicationContext.getBean(handlerClass, IEidasAttributeHandler.class);
+
+ log.trace("Perfom request-validastion by using: {}", handler.getClass().getName());
+ handler.validateAuthnRequest(eidasRequest);
+
+ } catch (BeansException e) {
+ log.error("No custom attribute-handler implementation for: {}. Operation can NOT be performed", handlerClass, e);
+
+ }
+ }
+
private void buildNationalRequestedAttributes(
ServiceProviderConfiguration spConfig, ILightRequest eidasRequest) {
final boolean mandatesEnabled = !SpMandateModes.NONE.equals(spConfig.getMandateMode());
diff --git a/modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties b/modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties
index 3f92d58a..34f0ee86 100644
--- a/modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties
+++ b/modules/eidas_proxy-sevice/src/main/resources/messages/eidasproxy_messages.properties
@@ -10,5 +10,6 @@ eidas.proxyservice.09=eIDAS authentication not possible, because legal person is
eidas.proxyservice.10=eIDAS authentication not possible, because legal person is requested but not mandate profiles are defined
eidas.proxyservice.11=No Authentication request with stated communication token.
+eidas.proxyservice.ejustice.01=eJustice attributes for natural and legal person can not supported in a single request.
eidas.proxyservice.99=Internal error during eIDAS Proxy-Service authentication \ No newline at end of file
diff --git a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerBorisTest.java b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerBorisTest.java
index dfa4e264..78ae87a5 100644
--- a/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerBorisTest.java
+++ b/modules/eidas_proxy-sevice/src/test/java/at/asitplus/eidas/specific/modules/msproxyservice/test/protocol/EidasProxyServiceControllerBorisTest.java
@@ -3,6 +3,7 @@ package at.asitplus.eidas.specific.modules.msproxyservice.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 java.io.IOException;
import java.net.URISyntaxException;
@@ -31,6 +32,7 @@ import at.asitplus.eidas.specific.modules.core.eidas.EidasConstants;
import at.asitplus.eidas.specific.modules.core.eidas.service.EidasAttributeRegistry;
import at.asitplus.eidas.specific.modules.core.eidas.test.dummy.DummySpecificCommunicationService;
import at.asitplus.eidas.specific.modules.msproxyservice.MsProxyServiceConstants;
+import at.asitplus.eidas.specific.modules.msproxyservice.exception.EidasProxyServiceException;
import at.asitplus.eidas.specific.modules.msproxyservice.protocol.EidasProxyServiceController;
import at.gv.egiz.eaaf.core.api.data.EaafConstants;
import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.SpMandateModes;
@@ -89,6 +91,52 @@ public class EidasProxyServiceControllerBorisTest {
}
@Test
+ public void bothBorisAttributesInSingleRequest() throws IOException, EaafException {
+ //initialize state
+ httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));
+ String spCountryCode = RandomStringUtils.randomAlphabetic(2).toUpperCase();
+ 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(spCountryCode)
+ .spType("public")
+ .requestedAttributes(ImmutableAttributeMap.builder()
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_LEGALNAME).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ EidasConstants.eIDAS_ATTR_LEGALPERSONIDENTIFIER).first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ "eJusticeLegalPersonRole").first())
+ .put(attrRegistry.getCoreAttributeRegistry().getByFriendlyName(
+ "eJusticeNaturalPersonRole").first())
+ .build());
+
+ proxyService.setiLightRequest(authnReqBuilder.build());
+
+
+ // set default mandate configuration
+ 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_NATURAL,
+ StringUtils.join(mandateProfilesNat, ","));
+ config.putConfigValue(MsProxyServiceConstants.CONIG_PROPS_EIDAS_PROXY_MANDATES_PROFILE_DEFAULT_LEGAL,
+ StringUtils.join(mandateProfilesJur, ","));
+
+
+ //execute
+ EidasProxyServiceException error = assertThrows("wrong exception", EidasProxyServiceException.class,
+ () -> controller.receiveEidasAuthnRequest(httpReq, httpResp));
+ assertEquals("wrong errorCode", "eidas.proxyservice.ejustice.01", error.getErrorId());
+
+ }
+
+ @Test
public void validAuthnRequestWithBorisAttributeLegal() throws IOException, EaafException {
//initialize state
httpReq.addParameter(EidasParameterKeys.TOKEN.toString(), RandomStringUtils.randomAlphanumeric(10));