diff options
Diffstat (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java')
-rw-r--r-- | eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java | 418 |
1 files changed, 0 insertions, 418 deletions
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java deleted file mode 100644 index 90be9a7a..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java +++ /dev/null @@ -1,418 +0,0 @@ -/* - * 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.auth.eidas.v2.handler; - -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Base64; -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 org.springframework.lang.NonNull; - -import com.google.common.collect.ImmutableSortedSet; - -import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.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.data.EaafConstants; -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.Triple; -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) { - - buildLevelOfAssurance(pendingReq.getServiceProviderConfiguration(), authnRequestBuilder); - buildProviderNameAndRequesterIdAttribute(pendingReq, authnRequestBuilder); - buildRequestedAttributes(authnRequestBuilder); - - } - - - @Override - public final ErnbEidData postProcess(Map<String, Object> eidasAttrMap) throws EidPostProcessingException, - EidasAttributeException { - final ErnbEidData result = new ErnbEidData(); - - final Object eIdentifierObj = eidasAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); - final Triple<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; - - } - - - /** - * Get a Map of country-specific requested attributes. - * - * @return - */ - @NonNull - protected abstract Map<String, Boolean> getCountrySpecificRequestedAttributes(); - - /** - * Post-Process the eIDAS CurrentAddress attribute. - * - * @param currentAddressObj eIDAS current address information - * @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) { - final PostalAddressType result = new PostalAddressType(); - result.setPostalCode(((PostalAddress) currentAddressObj).getPostCode()); - result.setMunicipality(((PostalAddress) currentAddressObj).getPostName()); - - // TODO: add more mappings - - return result; - - } 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 eIDAS birthname information - * @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 eIDAS Place-of-Birth information - * @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 eIDAS date-of-birth attribute information - * @return formated user's date-of-birth - * @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 eIDAS givenName attribute information - * @return formated user's givenname - * @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 eIDAS familyName attribute information - * @return formated user's familyname - * @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 personalIdObj eIDAS PersonalIdentifierAttribute - * @return Unique personal identifier without country-code information - * @throws EidasAttributeException if NO attribute is available - * @throws EidPostProcessingException if post-processing fails - */ - protected String processPseudonym(Object personalIdObj) throws EidPostProcessingException, - EidasAttributeException { - if (personalIdObj == null || !(personalIdObj instanceof String)) { - throw new EidasAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); - } - - final Triple<String, String, String> eIdentifier = - EidasResponseUtils.parseEidasPersonalIdentifier((String) personalIdObj); - - return eIdentifier.getThird(); - - } - - /** - * Set ProviderName and RequestId into eIDAS AuthnRequest. - * - * @param pendingReq Current pendingRequest - * @param authnRequestBuilder AuthnREquest builer - */ - protected void buildProviderNameAndRequesterIdAttribute(IRequest pendingReq, Builder authnRequestBuilder) { - final ISpConfiguration spConfig = pendingReq.getServiceProviderConfiguration(); - - // set correct SPType for requested target sector - final String publicSectorTargetSelector = basicConfig.getBasicConfiguration( - Constants.CONIG_PROPS_EIDAS_NODE_PUBLICSECTOR_TARGETS, - Constants.POLICY_DEFAULT_ALLOWED_TARGETS); - final Pattern p = Pattern.compile(publicSectorTargetSelector); - final Matcher m = p.matcher(spConfig.getAreaSpecificTargetIdentifier()); - if (m.matches()) { - log.debug("Map " + spConfig.getAreaSpecificTargetIdentifier() + " to 'PublicSector'"); - authnRequestBuilder.spType(SpType.PUBLIC.getValue()); - - final String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class); - if (basicConfig.getBasicConfigurationBoolean( - Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME, - false)) { - //TODO: only for eIDAS ref. node 2.0 and 2.1 because it need 'Providername' for - if (StringUtils.isNotEmpty(providerName)) { - log.debug("Set 'providername' to: {}", providerName); - authnRequestBuilder.providerName(providerName); - - } else { - 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 { - 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 - final String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class); - if (StringUtils.isNotEmpty(providerName)) { - authnRequestBuilder.providerName(providerName); - - } - - authnRequestBuilder.requesterId( - generateRequesterId(pendingReq.getRawData(Constants.DATA_REQUESTERID, String.class))); - - } - } - - private String generateRequesterId(String requesterId) { - if (requesterId != null && basicConfig.getBasicConfigurationBoolean( - Constants.CONIG_PROPS_EIDAS_NODE_REQUESTERID_USE_HASHED_VERSION, true)) { - try { - log.trace("Building hashed 'requesterId' for private SP ... "); - MessageDigest digest = MessageDigest.getInstance("SHA-256"); - String encodedRequesterId = Base64.getEncoder().encodeToString( - digest.digest(requesterId.getBytes(StandardCharsets.UTF_8))); - log.debug("Set 'requesterId' for: {} to: {}", requesterId, encodedRequesterId); - return encodedRequesterId; - - } catch (NoSuchAlgorithmException e) { - log.error("Can NOT generate hashed 'requesterId' from: {}. Use it as it is", requesterId, e); - - } - - } - - return requesterId; - - } - - - private void buildRequestedAttributes(Builder authnRequestBuilder) { - // build and add requested attribute set - final Map<String, Boolean> ccSpecificReqAttr = getCountrySpecificRequestedAttributes(); - log.debug("Get #{} country-specific requested attributes", ccSpecificReqAttr.size()); - - final 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 - final ImmutableAttributeMap reqAttrMap = translateToEidasAttributes(ccSpecificReqAttr); - authnRequestBuilder.requestedAttributes(reqAttrMap); - - } - - private ImmutableAttributeMap translateToEidasAttributes(final Map<String, Boolean> requiredAttributes) { - final ImmutableAttributeMap.Builder builder = ImmutableAttributeMap.builder(); - for (final 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 buildLevelOfAssurance(ISpConfiguration spConfig, Builder authnRequestBuilder) { - // TODO: set matching mode if eIDAS ref. impl. support this method - - // TODO: update if eIDAS ref. impl. supports exact matching for non-notified LoA - // schemes - String loa = EaafConstants.EIDAS_LOA_HIGH; - if (spConfig.getRequiredLoA() != null) { - if (spConfig.getRequiredLoA().isEmpty()) { - log.info("No eIDAS LoA requested. Use LoA HIGH as default"); - } else { - if (spConfig.getRequiredLoA().size() > 1) { - log.info( - "Currently only ONE requested LoA is supported for service provider. Use first one ... "); - } - - loa = spConfig.getRequiredLoA().get(0); - - } - } - - log.debug("Request eIdAS node with LoA: " + loa); - authnRequestBuilder.levelOfAssurance(loa); - - } - -} |