aboutsummaryrefslogtreecommitdiff
path: root/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/AbstracteIDProcessor.java
diff options
context:
space:
mode:
Diffstat (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/AbstracteIDProcessor.java')
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/AbstracteIDProcessor.java337
1 files changed, 337 insertions, 0 deletions
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/AbstracteIDProcessor.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/AbstracteIDProcessor.java
new file mode 100644
index 00000000..34b3017f
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/AbstracteIDProcessor.java
@@ -0,0 +1,337 @@
+/*******************************************************************************
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ *******************************************************************************/
+package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.handler;
+
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.google.common.collect.ImmutableSortedSet;
+
+import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.Constants;
+import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.DAO.ERnBeIDData;
+import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASAttributeException;
+import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.eIDPostProcessingException;
+import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.service.eIDASAttributeRegistry;
+import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.utils.eIDASResponseUtils;
+import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP;
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.impl.data.Trible;
+import edu.umd.cs.findbugs.annotations.NonNull;
+import eu.eidas.auth.commons.attribute.AttributeDefinition;
+import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
+import eu.eidas.auth.commons.light.impl.LightRequest.Builder;
+import eu.eidas.auth.commons.protocol.eidas.SpType;
+import eu.eidas.auth.commons.protocol.eidas.impl.PostalAddress;
+
+public abstract class AbstracteIDProcessor implements INationaleIDProcessor {
+ private static final Logger log = LoggerFactory.getLogger(AbstracteIDProcessor.class);
+
+ @Autowired protected eIDASAttributeRegistry attrRegistry;
+ @Autowired protected IConfigurationWithSP basicConfig;
+
+ @Override
+ public final void preProcess(IRequest pendingReq, Builder authnRequestBuilder) {
+
+ buildProviderNameAttribute(pendingReq, authnRequestBuilder);
+ buildRequestedAttributes(pendingReq, authnRequestBuilder);
+
+
+ }
+
+ @Override
+ public final ERnBeIDData postProcess(Map<String, Object> eIDASAttrMap) throws eIDPostProcessingException, eIDASAttributeException{
+ ERnBeIDData result = new ERnBeIDData();
+
+ Object eIdentifierObj = eIDASAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+ Trible<String, String, String> eIdentifier =
+ eIDASResponseUtils.parseEidasPersonalIdentifier((String)eIdentifierObj);
+ result.setCitizenCountryCode(eIdentifier.getFirst());
+
+ //MDS attributes
+ result.setPseudonym(processPseudonym(eIDASAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER)));
+ result.setFamilyName(processFamilyName(eIDASAttrMap.get(Constants.eIDAS_ATTR_CURRENTFAMILYNAME)));
+ result.setGivenName(processGivenName(eIDASAttrMap.get(Constants.eIDAS_ATTR_CURRENTGIVENNAME)));
+ result.setDateOfBirth(processDateOfBirth(eIDASAttrMap.get(Constants.eIDAS_ATTR_DATEOFBIRTH)));
+
+ //additional attributes
+ result.setPlaceOfBirth(processPlaceOfBirth(eIDASAttrMap.get(Constants.eIDAS_ATTR_PLACEOFBIRTH)));
+ result.setBirthName(processBirthName(eIDASAttrMap.get(Constants.eIDAS_ATTR_BIRTHNAME)));
+ result.setAddress(processAddress(eIDASAttrMap.get(Constants.eIDAS_ATTR_CURRENTADDRESS)));
+
+ return result;
+
+ }
+
+ @NonNull
+ /**
+ * Get a Map of country-specific requested attributes
+ *
+ * @return
+ */
+ protected abstract Map<String, Boolean> getCountrySpecificRequestedAttributes();
+
+ /**
+ * Post-Process the eIDAS CurrentAddress attribute
+ *
+ * @param currentAddressObj
+ * @return current address or null if no attribute is available
+ * @throws eIDPostProcessingException if post-processing fails
+ * @throws eIDASAttributeException if eIDAS attribute is of a wrong type
+ */
+ protected PostalAddressType processAddress(Object currentAddressObj) throws eIDPostProcessingException, eIDASAttributeException {
+
+ if (currentAddressObj != null) {
+ if ((currentAddressObj instanceof PostalAddress)) {
+ PostalAddressType result = new PostalAddressType();
+ result.setPostalCode(((PostalAddress)currentAddressObj).getPostCode());
+ result.setMunicipality(((PostalAddress)currentAddressObj).getPostName());
+
+ //TODO: add more mappings
+
+ } else {
+ log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_CURRENTADDRESS + " is of WRONG type");
+ throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTADDRESS);
+
+ }
+
+ } else
+ log.debug("NO '" + Constants.eIDAS_ATTR_CURRENTADDRESS + "' attribute. Post-Processing skipped ... ");
+
+ return null;
+
+ }
+
+ /**
+ * Post-Process the eIDAS BirthName attribute
+ *
+ * @param birthNameObj
+ * @return birthName or null if no attribute is available
+ * @throws eIDPostProcessingException if post-processing fails
+ * @throws eIDASAttributeException if eIDAS attribute is of a wrong type
+ */
+ protected String processBirthName(Object birthNameObj) throws eIDPostProcessingException, eIDASAttributeException {
+ if (birthNameObj != null) {
+ if ((birthNameObj instanceof String)) {
+ return (String)birthNameObj;
+
+ } else {
+ log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_BIRTHNAME + " is of WRONG type");
+ throw new eIDASAttributeException(Constants.eIDAS_ATTR_BIRTHNAME);
+
+ }
+
+ } else
+ log.debug("NO '" + Constants.eIDAS_ATTR_BIRTHNAME + "' attribute. Post-Processing skipped ... ");
+
+
+ return null;
+
+ }
+
+ /**
+ * Post-Process the eIDAS PlaceOfBirth attribute
+ *
+ * @param placeOfBirthObj
+ * @return place of Birth or null if no attribute is available
+ * @throws eIDPostProcessingException if post-processing fails
+ * @throws eIDASAttributeException if eIDAS attribute is of a wrong type
+ */
+ protected String processPlaceOfBirth(Object placeOfBirthObj) throws eIDPostProcessingException, eIDASAttributeException {
+ if (placeOfBirthObj != null) {
+ if ((placeOfBirthObj instanceof String)) {
+ return (String)placeOfBirthObj;
+
+ } else {
+ log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_PLACEOFBIRTH + " is of WRONG type");
+ throw new eIDASAttributeException(Constants.eIDAS_ATTR_PLACEOFBIRTH);
+
+ }
+
+ } else
+ log.debug("NO '" + Constants.eIDAS_ATTR_PLACEOFBIRTH + "' attribute. Post-Processing skipped ... ");
+
+
+ return null;
+
+ }
+
+ /**
+ * Post-Process the eIDAS DateOfBirth attribute
+ *
+ * @param dateOfBirthObj
+ * @return
+ * @throws eIDASAttributeException if NO attribute is available
+ * @throws eIDPostProcessingException if post-processing fails
+ */
+ protected DateTime processDateOfBirth(Object dateOfBirthObj) throws eIDPostProcessingException, eIDASAttributeException {
+ if (dateOfBirthObj == null || !(dateOfBirthObj instanceof DateTime))
+ throw new eIDASAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH);
+
+ return (DateTime)dateOfBirthObj;
+
+ }
+
+ /**
+ * Post-Process the eIDAS GivenName attribute
+ *
+ * @param givenNameObj
+ * @return
+ * @throws eIDASAttributeException if NO attribute is available
+ * @throws eIDPostProcessingException if post-processing fails
+ */
+ protected String processGivenName(Object givenNameObj) throws eIDPostProcessingException, eIDASAttributeException {
+ if (givenNameObj == null || !(givenNameObj instanceof String))
+ throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTGIVENNAME);
+
+ return (String)givenNameObj;
+
+ }
+
+ /**
+ * Post-Process the eIDAS FamilyName attribute
+ *
+ * @param familyNameObj
+ * @return
+ * @throws eIDASAttributeException if NO attribute is available
+ * @throws eIDPostProcessingException if post-processing fails
+ */
+ protected String processFamilyName(Object familyNameObj) throws eIDPostProcessingException, eIDASAttributeException {
+ if (familyNameObj == null || !(familyNameObj instanceof String))
+ throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTFAMILYNAME);
+
+ return (String) familyNameObj;
+
+ }
+
+ /**
+ * Post-Process the eIDAS pseudonym to ERnB unique identifier
+ *
+ * @param eIdentifierObj eIDAS PersonalIdentifierAttribute
+ * @return
+ * @throws eIDPostProcessingException
+ * @throws eIDASAttributeException if NO attribute is available
+ * @throws eIDPostProcessingException if post-processing fails
+ */
+ protected String processPseudonym(Object eIdentifierObj) throws eIDPostProcessingException, eIDASAttributeException {
+ if (eIdentifierObj == null || !(eIdentifierObj instanceof String))
+ throw new eIDASAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+
+ Trible<String, String, String> eIdentifier =
+ eIDASResponseUtils.parseEidasPersonalIdentifier((String)eIdentifierObj);
+
+ return eIdentifier.getThird();
+
+ }
+
+ private void buildRequestedAttributes(IRequest pendingReq, Builder authnRequestBuilder) {
+ //build and add requested attribute set
+ Map<String, Boolean> ccSpecificReqAttr = getCountrySpecificRequestedAttributes();
+ log.debug("Get #{} country-specific requested attributes", ccSpecificReqAttr.size());
+
+ Map<String, Boolean> mdsReqAttr = attrRegistry.getDefaultAttributeSetFromConfiguration();
+ log.trace("Get #{} default requested attributes", mdsReqAttr.size());
+
+ //put it together
+ ccSpecificReqAttr.putAll(mdsReqAttr);
+
+ //convert it to eIDAS attributes
+ ImmutableAttributeMap reqAttrMap = translateToEidasAttributes(ccSpecificReqAttr);
+ authnRequestBuilder.requestedAttributes(reqAttrMap);
+
+ }
+
+ private ImmutableAttributeMap translateToEidasAttributes(final Map<String, Boolean> requiredAttributes) {
+ ImmutableAttributeMap.Builder builder = ImmutableAttributeMap.builder();
+ for (Map.Entry<String,Boolean> attribute : requiredAttributes.entrySet()) {
+ final String name = attribute.getKey();
+ final ImmutableSortedSet<AttributeDefinition<?>> byFriendlyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(name);
+ if (!byFriendlyName.isEmpty()) {
+ final AttributeDefinition<?> attributeDefinition = byFriendlyName.first();
+ builder.put(AttributeDefinition.builder(attributeDefinition).required(attribute.getValue()).build());
+
+ } else
+ log.warn("Can NOT request UNKNOWN attribute: " + attribute.getKey() + " Ignore it!");
+
+ }
+
+ return builder.build();
+
+ }
+
+ private void buildProviderNameAttribute(IRequest pendingReq, Builder authnRequestBuilder) {
+ ISPConfiguration spConfig = pendingReq.getServiceProviderConfiguration();
+
+ //set correct SPType for requested target sector
+ String publicSectorTargetSelector = basicConfig.getBasicConfiguration(
+ Constants.CONIG_PROPS_EIDAS_NODE_PUBLICSECTOR_TARGETS,
+ Constants.POLICY_DEFAULT_ALLOWED_TARGETS);
+ Pattern p = Pattern.compile(publicSectorTargetSelector);
+ Matcher m = p.matcher(spConfig.getAreaSpecificTargetIdentifier());
+ if (m.matches()) {
+ log.debug("Map " + spConfig.getAreaSpecificTargetIdentifier() + " to 'PublicSector'");
+ authnRequestBuilder.spType(SpType.PUBLIC.getValue());
+
+ if ( basicConfig.getBasicConfigurationBoolean(
+ Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_USE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP,
+ false) ) {
+ authnRequestBuilder.providerName(basicConfig.getBasicConfiguration(
+ Constants.CONIG_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP,
+ Constants.DEFAULT_PROPS_EIDAS_NODE_STATIC_PROVIDERNAME_FOR_PUBLIC_SP));
+
+ } else {
+ //TODO: only for eIDAS ref. node 2.0 and 2.1 because it need 'Providername' for any SPType
+ String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class);
+ if ( StringUtils.isNotEmpty(providerName)
+ && basicConfig.getBasicConfigurationBoolean(
+ Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME,
+ false)
+ ) {
+ authnRequestBuilder.providerName(providerName);
+
+ }
+ }
+
+ } else {
+ log.debug("Map " + spConfig.getAreaSpecificTargetIdentifier() + " to 'PrivateSector'");
+ authnRequestBuilder.spType(SpType.PRIVATE.getValue());
+
+ //TODO: switch to RequesterId in further version
+ //set provider name for private sector applications
+ String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class);
+ if (StringUtils.isNotEmpty(providerName))
+ authnRequestBuilder.providerName(providerName);
+
+ }
+
+ }
+
+}