diff options
author | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2019-10-31 09:48:29 +0100 |
---|---|---|
committer | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2019-10-31 09:48:29 +0100 |
commit | 6bd9903633452f01531e9830db0242e9bf081242 (patch) | |
tree | 5745138b439e469cfc9f10ddea60cb71c8d467eb /eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus | |
parent | 5bda3bcc87f7c58dfa782e76eecb183631369ede (diff) | |
download | National_eIDAS_Gateway-6bd9903633452f01531e9830db0242e9bf081242.tar.gz National_eIDAS_Gateway-6bd9903633452f01531e9830db0242e9bf081242.tar.bz2 National_eIDAS_Gateway-6bd9903633452f01531e9830db0242e9bf081242.zip |
add country specific pre-processing to build country specific eIDAS requests
Diffstat (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
10 files changed, 240 insertions, 104 deletions
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/Constants.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/Constants.java index bceb9beb..5362431f 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/Constants.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/Constants.java @@ -55,7 +55,8 @@ public class Constants { public static final String CONIG_PROPS_EIDAS_NODE_ENTITYID = CONIG_PROPS_EIDAS_NODE + ".entityId"; public static final String CONIG_PROPS_EIDAS_NODE_FORWARD_URL = CONIG_PROPS_EIDAS_NODE + ".forward.endpoint"; public static final String CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD = CONIG_PROPS_EIDAS_NODE + ".forward.method"; - public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_ONLYNATURAL = CONIG_PROPS_EIDAS_NODE + ".attributes.requested.onlynatural."; + public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_DEFAULT_ONLYNATURAL = CONIG_PROPS_EIDAS_NODE + ".attributes.requested.onlynatural."; + public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_CC_SPECIFIC_ONLYNATURAL = CONIG_PROPS_EIDAS_NODE + ".attributes.requested.{0}.onlynatural."; public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_REPRESENTATION = CONIG_PROPS_EIDAS_NODE + ".attributes.requested.representation."; public static final String CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME = CONIG_PROPS_EIDAS_NODE + ".workarounds.addAlwaysProviderName"; public static final String CONIG_PROPS_EIDAS_NODE_WORKAROUND_USEREQUESTIDASTRANSACTIONIDENTIFIER = CONIG_PROPS_EIDAS_NODE + ".workarounds.useRequestIdAsTransactionIdentifier"; diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/AbstracteIDPostProcessor.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/AbstracteIDProcessor.java index 9c252d1d..34b3017f 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/AbstracteIDPostProcessor.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/AbstracteIDProcessor.java @@ -23,26 +23,52 @@ 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 AbstracteIDPostProcessor implements INationaleIDPostProcessor { - private static final Logger log = LoggerFactory.getLogger(AbstracteIDPostProcessor.class); +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 ERnBeIDData postProcess(Map<String, Object> eIDASAttrMap) throws eIDPostProcessingException, eIDASAttributeException{ + 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); @@ -65,6 +91,14 @@ public abstract class AbstracteIDPostProcessor implements INationaleIDPostProces } + @NonNull + /** + * Get a Map of country-specific requested attributes + * + * @return + */ + protected abstract Map<String, Boolean> getCountrySpecificRequestedAttributes(); + /** * Post-Process the eIDAS CurrentAddress attribute * @@ -218,4 +252,86 @@ public abstract class AbstracteIDPostProcessor implements INationaleIDPostProces } + 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); + + } + + } + } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/DEeIDPostProcessor.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/DEeIDProcessor.java index e017e3a4..a3880b3f 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/DEeIDPostProcessor.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/DEeIDProcessor.java @@ -23,6 +23,7 @@ package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.handler; import java.util.Base64; +import java.util.Map; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; @@ -35,8 +36,8 @@ import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.eIDPostPr import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.utils.eIDASResponseUtils; import at.gv.egiz.eaaf.core.impl.data.Trible; -public class DEeIDPostProcessor extends AbstracteIDPostProcessor { - private static final Logger log = LoggerFactory.getLogger(DEeIDPostProcessor.class); +public class DEeIDProcessor extends AbstracteIDProcessor { + private static final Logger log = LoggerFactory.getLogger(DEeIDProcessor.class); private static final String canHandleCC = "DE"; private int priority = 1; @@ -98,4 +99,10 @@ public class DEeIDPostProcessor extends AbstracteIDPostProcessor { return new String(encoded); } + @Override + protected Map<String, Boolean> getCountrySpecificRequestedAttributes() { + return attrRegistry.getAttributeSetFromConfiguration(canHandleCC); + + } + } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/GenericeIDPostProcessor.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/GenericeIDProcessor.java index 026965fc..110635d9 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/GenericeIDPostProcessor.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/GenericeIDProcessor.java @@ -22,7 +22,10 @@ *******************************************************************************/ package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.handler; -public class GenericeIDPostProcessor extends AbstracteIDPostProcessor { +import java.util.HashMap; +import java.util.Map; + +public class GenericeIDProcessor extends AbstracteIDProcessor { private int priority = 0; @@ -47,7 +50,11 @@ public class GenericeIDPostProcessor extends AbstracteIDPostProcessor { return "Default-PostProcessor"; } - - + @Override + protected Map<String, Boolean> getCountrySpecificRequestedAttributes() { + return new HashMap<>(); + + } + } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/INationaleIDPostProcessor.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/INationaleIDProcessor.java index b34e9c41..46cfcb2b 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/INationaleIDPostProcessor.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/handler/INationaleIDProcessor.java @@ -27,8 +27,11 @@ import java.util.Map; 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.gv.egiz.eaaf.core.api.IRequest; +import eu.eidas.auth.commons.light.ILightRequest; +import eu.eidas.auth.commons.light.impl.LightRequest.Builder; -public interface INationaleIDPostProcessor { +public interface INationaleIDProcessor { /** * Get a friendlyName of this post-processor implementation @@ -57,6 +60,8 @@ public interface INationaleIDPostProcessor { public boolean canHandle(String countryCode); + + /** * Post-Process eIDAS eID data into national format * @param eIDASAttrMap Map of eIDAS attributes in format friendlyName and attribute @@ -64,5 +69,13 @@ public interface INationaleIDPostProcessor { * @throws eIDASAttributeException * */ - public ERnBeIDData postProcess(Map<String, Object> eIDASAttrMap) throws eIDPostProcessingException, eIDASAttributeException; + public ERnBeIDData postProcess(Map<String, Object> eIDASAttrMap) throws eIDPostProcessingException, eIDASAttributeException; + + /** + * Pre-Process eIDAS Request to national requirements + * + * @param pendingReq current pending request + * @param authnRequestBuilder eIDAS {@link ILightRequest} builder + */ + public void preProcess(IRequest pendingReq, Builder authnRequestBuilder); } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/EIDPostProcessingService.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/CCSpecificEIDProcessingService.java index 331b2641..602982d6 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/EIDPostProcessingService.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/CCSpecificEIDProcessingService.java @@ -43,34 +43,36 @@ 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.handler.INationaleIDPostProcessor; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.handler.INationaleIDProcessor; import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.utils.eIDASResponseUtils; +import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.impl.data.Trible; +import eu.eidas.auth.commons.light.impl.LightRequest.Builder; @Service -public class EIDPostProcessingService implements IeIDPostProcessingService{ - private static final Logger log = LoggerFactory.getLogger(EIDPostProcessingService.class); +public class CCSpecificEIDProcessingService implements ICCSpecificEIDProcessingService{ + private static final Logger log = LoggerFactory.getLogger(CCSpecificEIDProcessingService.class); @Autowired private ApplicationContext context; - private List<INationaleIDPostProcessor> handlers = new ArrayList<INationaleIDPostProcessor>(); + private List<INationaleIDProcessor> handlers = new ArrayList<INationaleIDProcessor>(); @PostConstruct private void initialize() { log.debug("Initialize eID PostProcessing-Service ... "); - Map<String, INationaleIDPostProcessor> postProcessors = context.getBeansOfType(INationaleIDPostProcessor.class); - Iterator<Entry<String, INationaleIDPostProcessor>> iterator = postProcessors.entrySet().iterator(); + Map<String, INationaleIDProcessor> postProcessors = context.getBeansOfType(INationaleIDProcessor.class); + Iterator<Entry<String, INationaleIDProcessor>> iterator = postProcessors.entrySet().iterator(); while (iterator.hasNext()) { - Entry<String, INationaleIDPostProcessor> el = iterator.next(); + Entry<String, INationaleIDProcessor> el = iterator.next(); log.debug("Find eID-PostProcessor with name: " + el.getKey()); handlers.add(el.getValue()); } log.trace("Sorting eID-PostProcessors on priority ... "); - Collections.sort(handlers, new Comparator<INationaleIDPostProcessor>() { + Collections.sort(handlers, new Comparator<INationaleIDProcessor>() { @Override - public int compare(INationaleIDPostProcessor thisAuthModule, INationaleIDPostProcessor otherAuthModule) { + public int compare(INationaleIDProcessor thisAuthModule, INationaleIDProcessor otherAuthModule) { int thisOrder = thisAuthModule.getPriority(); int otherOrder = otherAuthModule.getPriority(); return (thisOrder < otherOrder ? 1 : (thisOrder == otherOrder ? 0 : -1)); @@ -82,6 +84,25 @@ public class EIDPostProcessingService implements IeIDPostProcessingService{ } @Override + public void preProcess(String selectedCitizenCountry, IRequest pendingReq, Builder authnRequestBuilder) throws eIDPostProcessingException { + if (StringUtils.isEmpty(selectedCitizenCountry)) + log.info("No CountryCode for eID Pre-Processor. Default Pre-Processor will be used"); + + for (INationaleIDProcessor el : handlers) { + if (el.canHandle(selectedCitizenCountry)) { + log.debug("Pre-Process eIDAS request for " + selectedCitizenCountry + " by using: " + el.getName()); + el.preProcess(pendingReq, authnRequestBuilder); + return; + + } + } + + log.error("NO eID PostProcessor FOUND. Looks like a depentency problem!"); + throw new eIDPostProcessingException("internal.00", null); + + } + + @Override public ERnBeIDData postProcess(Map<String, Object> eIDASAttrMap) throws eIDPostProcessingException, eIDASAttributeException { //extract citizen country from eIDAS unique identifier Object eIdentifierObj = eIDASAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); @@ -95,7 +116,7 @@ public class EIDPostProcessingService implements IeIDPostProcessingService{ if (StringUtils.isEmpty(citizenCountry)) log.info("No CountryCode for eID PostProcessor. Default-PostProcessor will be used"); - for (INationaleIDPostProcessor el : handlers) { + for (INationaleIDProcessor el : handlers) { if (el.canHandle(citizenCountry)) { log.debug("Post-Process eIDAS eID from " + citizenCountry + " by using: " + el.getName()); return el.postProcess(eIDASAttrMap); diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/IeIDPostProcessingService.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/ICCSpecificEIDProcessingService.java index 02d18920..02802126 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/IeIDPostProcessingService.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/ICCSpecificEIDProcessingService.java @@ -27,8 +27,11 @@ import java.util.Map; 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.gv.egiz.eaaf.core.api.IRequest; +import eu.eidas.auth.commons.light.ILightRequest; +import eu.eidas.auth.commons.light.impl.LightRequest.Builder; -public interface IeIDPostProcessingService { +public interface ICCSpecificEIDProcessingService { /** * Post-process eIDAS eID attributes into national format @@ -40,5 +43,15 @@ public interface IeIDPostProcessingService { * @throws eIDASAttributeException */ public ERnBeIDData postProcess(Map<String, Object> eIDASAttrMap) throws eIDPostProcessingException, eIDASAttributeException; + + /** + * Pre Process eIDAS request into national requirements + * + * @param selectedCC Citizen Country from selection + * @param pendingReq current pending request + * @param authnRequestBuilder eIDAS {@link ILightRequest} builder + * @throws eIDPostProcessingException + */ + public void preProcess(String selectedCC, IRequest pendingReq, Builder authnRequestBuilder) throws eIDPostProcessingException; } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/eIDASAttributeRegistry.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/eIDASAttributeRegistry.java index 116f2197..6e934c59 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/eIDASAttributeRegistry.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/eIDASAttributeRegistry.java @@ -23,6 +23,7 @@ package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.service; import java.io.File; +import java.text.MessageFormat; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -39,6 +40,7 @@ import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.Constants; import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP; import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; +import edu.umd.cs.findbugs.annotations.NonNull; import eu.eidas.auth.commons.attribute.AttributeRegistries; import eu.eidas.auth.commons.attribute.AttributeRegistry; @@ -93,8 +95,25 @@ public class eIDASAttributeRegistry { return coreAttributeRegistry; } - public Map<String, Boolean> getAttributeSetFromConfiguration() { - Map<String, Boolean> result = new HashMap<String, Boolean>(); + @NonNull + public Map<String, Boolean> getDefaultAttributeSetFromConfiguration() { + /*TODO: select set for representation if mandates should be used. + * It's an open task in respect to requested eIDAS attributes and isRequired flag, + * because there can be a decision problem in case of natural or legal person representation! + * From an Austrian use-case point of view, an Austrian service provider can support mandates for + * natural and legal persons at the same time. However, we CAN NOT request attributes for natural AND + * legal persons on the same time, because it's not possible to represent both simultaneously. + */ + Map<String, String> configAttributes = + basicConfig.getBasicConfigurationWithPrefix( + Constants.CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_DEFAULT_ONLYNATURAL); + return processAttributeInfosFromConfig(configAttributes); + + } + + @NonNull + public Map<String, Boolean> getAttributeSetFromConfiguration(String countryCode) { + /*TODO: select set for representation if mandates should be used. * It's an open task in respect to requested eIDAS attributes and isRequired flag, @@ -105,7 +124,16 @@ public class eIDASAttributeRegistry { */ Map<String, String> configAttributes = basicConfig.getBasicConfigurationWithPrefix( - Constants.CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_ONLYNATURAL); + MessageFormat.format( + Constants.CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_CC_SPECIFIC_ONLYNATURAL, + countryCode.toLowerCase())); + return processAttributeInfosFromConfig(configAttributes); + + } + + private Map<String, Boolean> processAttributeInfosFromConfig(Map<String, String> configAttributes) { + + Map<String, Boolean> result = new HashMap<String, Boolean>(); for (String el: configAttributes.values()) { if (StringUtils.isNotEmpty(el.trim())) { List<String> attrDef = KeyValueUtils.getListOfCSVValues(el.trim()); @@ -122,8 +150,7 @@ public class eIDASAttributeRegistry { return result; } - - + public void setEidasAttributesFile(String eidasAttributesFile) { this.eidasAttributesFile = eidasAttributesFile; } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java index cc1d6ae4..3f27ca64 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java @@ -50,7 +50,7 @@ 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.SZRCommunicationException; import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASAttributeException; -import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.service.IeIDPostProcessingService; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.service.ICCSpecificEIDProcessingService; import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.szr.SZRClient; import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.utils.eIDASResponseUtils; import at.gv.e_government.reference.namespace.persondata._20020228.AlternativeNameType; @@ -88,7 +88,7 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask { @Autowired private IConfiguration basicConfig; @Autowired private SZRClient szrClient; - @Autowired private IeIDPostProcessingService eIDPostProcessor; + @Autowired private ICCSpecificEIDProcessingService eIDPostProcessor; /* (non-Javadoc) * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java index f49ed203..a522feb6 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java @@ -24,10 +24,7 @@ *******************************************************************************/ package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.tasks; -import java.util.Map; import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -41,14 +38,12 @@ import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import org.springframework.web.util.UriComponentsBuilder; -import com.google.common.collect.ImmutableSortedSet; - import at.asitplus.eidas.specific.connector.MSConnectorEventCodes; import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; import at.asitplus.eidas.specific.connector.gui.StaticGuiBuilderConfiguration; import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.Constants; import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASAuthenticationException; -import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.service.eIDASAttributeRegistry; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.service.ICCSpecificEIDProcessingService; import at.gv.egiz.eaaf.core.api.data.EAAFConstants; import at.gv.egiz.eaaf.core.api.gui.ISpringMVCGUIFormBuilder; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; @@ -59,11 +54,8 @@ import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; import eu.eidas.auth.commons.EidasParameterKeys; -import eu.eidas.auth.commons.attribute.AttributeDefinition; -import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; import eu.eidas.auth.commons.light.ILightRequest; import eu.eidas.auth.commons.light.impl.LightRequest; -import eu.eidas.auth.commons.protocol.eidas.SpType; import eu.eidas.auth.commons.tx.BinaryLightToken; import eu.eidas.specificcommunication.BinaryLightTokenHelper; import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; @@ -79,10 +71,10 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { private static final Logger log = LoggerFactory.getLogger(GenerateAuthnRequestTask.class); @Autowired IConfiguration basicConfig; - @Autowired eIDASAttributeRegistry attrRegistry; @Autowired ApplicationContext context; @Autowired ITransactionStorage transactionStore; @Autowired ISpringMVCGUIFormBuilder guiBuilder; + @Autowired ICCSpecificEIDProcessingService ccSpecificProcessing; @Override public void execute(ExecutionContext executionContext, @@ -142,49 +134,7 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { log.debug("Request eIdAS node with LoA: " + loa); authnRequestBuilder.levelOfAssurance(loa); - - //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); - - } - + //set nameIDFormat authnRequestBuilder.nameIdFormat(Constants.eIDAS_REQ_NAMEID_FORMAT); @@ -196,11 +146,10 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { * eIDASNode implements limit on size for RelayState (80characaters) */ //authnRequestBuilder.relayState(pendingReq.getPendingRequestId()); + + //Add country-specific informations into eIDAS request + ccSpecificProcessing.preProcess(citizenCountryCode, pendingReq, authnRequestBuilder); - //build and add requested attribute set - ImmutableAttributeMap reqAttrMap = translateToEidasAttributes(attrRegistry.getAttributeSetFromConfiguration()); - authnRequestBuilder.requestedAttributes(reqAttrMap); - //build request LightRequest lightAuthnReq = authnRequestBuilder.build(); @@ -305,24 +254,6 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { return null; } - - 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 BinaryLightToken putRequestInCommunicationCache(ILightRequest iLightRequest) throws ServletException { final BinaryLightToken binaryLightToken; |