/* * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a * cooperation between EGIZ, A-SIT Plus, 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 "Licence"); You may not use this work except in * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * * Unless required by applicable law or agreed to in writing, software distributed under the Licence * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the Licence for the specific language governing permissions and limitations under * the Licence. * * 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.gv.egiz.eaaf.core.impl.idp.auth.builder; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Map.Entry; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.data.EaafConstants; import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions; import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions; import at.gv.egiz.eaaf.core.api.idp.IAuthData; import at.gv.egiz.eaaf.core.api.idp.IAuthenticationDataBuilder; import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP; import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration; import at.gv.egiz.eaaf.core.api.idp.auth.data.IAuthProcessDataContainer; import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException; import at.gv.egiz.eaaf.core.exceptions.EaafBuilderException; import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; import at.gv.egiz.eaaf.core.exceptions.EaafException; import at.gv.egiz.eaaf.core.exceptions.EaafParserException; import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; import at.gv.egiz.eaaf.core.exceptions.XPathException; import at.gv.egiz.eaaf.core.impl.data.Pair; import at.gv.egiz.eaaf.core.impl.idp.AuthenticationData; import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper; import at.gv.egiz.eaaf.core.impl.idp.auth.data.SimpleIdentityLinkAssertionParser; import at.gv.egiz.eaaf.core.impl.utils.XPathUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; import org.springframework.util.Assert; import org.springframework.util.Base64Utils; import org.w3c.dom.DOMException; import org.w3c.dom.Element; import org.w3c.dom.Node; public abstract class AbstractAuthenticationDataBuilder implements IAuthenticationDataBuilder { private static final Logger log = LoggerFactory.getLogger(AbstractAuthenticationDataBuilder.class); /** * Identify authProcessData that should be directly mapped into authData. */ public static final String GENERIC_AUTHDATA_IDENTIFIER = "authData_"; public static final String CONFIG_PROP_ENABLE_IDL_ATTRIBUTE_ESCAPEING = "configuration.bugfix.enable.idl.escaping"; protected Collection includedToGenericAuthData = null; @Autowired protected IConfigurationWithSP basicConfig; @Override public IAuthData buildAuthenticationData(final IRequest pendingReq) throws EaafAuthenticationException { IAuthData authData = null; final IAuthProcessDataContainer authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class); try { if (authProcessData.isEidProcess()) { log.debug("Building AuthData from new E-ID information ... "); authData = getAuthDataInstance(pendingReq); Assert.notNull(authData, "AuthData is null"); log.trace("Adding generic AuthData information ... "); buildInternalAuthDataGeneric(authData, authProcessData, pendingReq); log.trace("Build service-specific AuthData information ... "); buildServiceSpecificAuthenticationData(authData, pendingReq); } else { log.info( "User authentication uses the deprecated. Building AuthData from deprecated information ... "); authData = buildDeprecatedAuthData(pendingReq); Assert.notNull(authData, "AuthData is null"); } } catch (final EaafAuthenticationException e) { throw e; } catch (XPathException | DOMException | EaafException e) { log.warn("Can not build authentication data from auth. process information"); throw new EaafAuthenticationException("builder.11", new Object[] { e.getMessage() }, e); } log.trace("AuthData generation finished"); return authData; } /** * * @param pendingReq current pendingRequest. * * @param pendingReq current pendingRequest * @return {@link IAuthData} but never null * @throws EaafException In case of an error */ @NonNull protected abstract IAuthData getAuthDataInstance(IRequest pendingReq) throws EaafException; /** * Build service-specific AuthData by using information from E-ID This builder * uses vSZ, MDS and Consent as input information. * * @param pendingReq current pendingRequest * @return {@link IAuthData} but never null * @throws EaafException In case of an error */ protected abstract void buildServiceSpecificAuthenticationData(IAuthData authData, IRequest pendingReq) throws EaafException; /** * Add generic E-ID information into already existing AuthData. * * @param authData AuthData object * @param authProcessData Authentication information holder from current pending * request * @param pendingReq current pending request * @throws EaafAuthenticationException In case inconsistent authentication data */ private void buildInternalAuthDataGeneric(@NonNull final IAuthData authData, @NonNull final IAuthProcessDataContainer authProcessData, @NonNull final IRequest pendingReq) throws EaafAuthenticationException { Assert.notNull(pendingReq, "PendingRequest is null"); Assert.notNull(authData, "AuthData is null"); Assert.notNull(authProcessData, "AuthProcessData is null"); if (!(authData instanceof AuthenticationData)) { log.error("AuthData has no suitable type! Requires: {}", AuthenticationData.class.getName()); throw new RuntimeException( "AuthData has no suitable type! Requires: " + AuthenticationData.class.getName()); } final AuthenticationData internalAuthData = (AuthenticationData) authData; // TODO: check if it is needed // if (authProcessData.getGenericSessionDataStorage() != null && // !authProcessData.getGenericSessionDataStorage().isEmpty()) // includedToGenericAuthData = // authProcessData.getGenericSessionDataStorage().keySet(); // else includedToGenericAuthData = new ArrayList<>(); // #################################################### // set general authData info's internalAuthData.setAuthenticationIssuer(pendingReq.getAuthUrl()); internalAuthData.setSsoSession(pendingReq.needSingleSignOnFunctionality()); internalAuthData.setBaseIdTransferRestrication( pendingReq.getServiceProviderConfiguration().hasBaseIdTransferRestriction()); // #################################################### // set MDS and vSZ internalAuthData.setFamilyName(authProcessData .getGenericDataFromSession(PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, String.class)); internalAuthData.setGivenName(authProcessData .getGenericDataFromSession(PvpAttributeDefinitions.GIVEN_NAME_NAME, String.class)); internalAuthData.setDateOfBirth(authProcessData .getGenericDataFromSession(PvpAttributeDefinitions.BIRTHDATE_NAME, String.class)); internalAuthData.setEncSourceId(authProcessData.getGenericDataFromSession( ExtendedPvpAttributeDefinitions.EID_ENCRYPTED_SOURCEID_NAME, String.class)); internalAuthData.setEncSourceIdType(authProcessData.getGenericDataFromSession( ExtendedPvpAttributeDefinitions.EID_ENCRYPTED_SOURCEID_TYPE_NAME, String.class)); // #################################################### // set QAA level setQaaLevel(internalAuthData, authProcessData); // #################################################### // set isForeigner flag setFlagForeigner(internalAuthData, authProcessData); // #################################################### // set citizen country-code setCitizenCountryCode(internalAuthData, authProcessData); // set generic authProcessData to authdata for (final Entry el : authProcessData.getGenericSessionDataStorage() .entrySet()) { if (el.getKey().startsWith(GENERIC_AUTHDATA_IDENTIFIER)) { log.trace("Find generic authProcessData {}. Map it directly to authData", el.getKey()); try { internalAuthData.setGenericData(el.getKey(), el.getValue()); } catch (final EaafStorageException e) { log.warn("Can NOT set authData with key: {}", el.getKey(), null, e); } } } } /** * Parse citzen country-code into AuthData. * * @param authData Current authentication data * @param authProcessData Authentication information holder from current pending * request * @throws EaafAuthenticationException In case inconsistent authentication data */ private void setCitizenCountryCode(final AuthenticationData authData, final IAuthProcessDataContainer authProcessData) throws EaafAuthenticationException { includedToGenericAuthData.remove(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME); final String pvpCccAttr = authProcessData .getGenericDataFromSession(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, String.class); if (StringUtils.isNotEmpty(pvpCccAttr)) { authData.setCiticenCountryCode(pvpCccAttr); log.debug("Find PVP-Attr: " + PvpAttributeDefinitions.EID_ISSUING_NATION_FRIENDLY_NAME); } else { if (authData.isForeigner()) { log.warn("EID_Issuing_Nation NOT SET for foreign citizen."); throw new EaafAuthenticationException("builder.11", new Object[] { "EID_Issuing_Nation NOT SET for foreign citizen." }); } else { authData.setCiticenCountryCode(basicConfig.getBasicConfiguration( IConfigurationWithSP.CONFIG_PROPS_AUTH_DEFAULT_COUNTRYCODE, EaafConstants.COUNTRYCODE_AUSTRIA)); } } } /** * parse QAA Level into AuthData. * * @param authData current authentication data * @param authProcessData Authentication information holder from current pending * request * @param pendingReq current pending request */ private void setQaaLevel(@NonNull final AuthenticationData authData, @NonNull final IAuthProcessDataContainer authProcessData) { includedToGenericAuthData.remove(PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME); String currentLoA = null; if (StringUtils.isNotEmpty(authProcessData.getQaaLevel())) { currentLoA = authProcessData.getQaaLevel(); } else { currentLoA = authProcessData.getGenericDataFromSession( PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, String.class); if (StringUtils.isNotEmpty(currentLoA)) { log.debug( "Find PVP-Attr '" + PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_FRIENDLY_NAME + "':" + currentLoA + " --> Parse QAA-Level from that attribute."); } } if (StringUtils.isNotEmpty(currentLoA)) { if (currentLoA.startsWith(EaafConstants.EIDAS_LOA_PREFIX)) { authData.setEidasLoa(currentLoA); } else { log.info("Only eIDAS LoAs are supported by this implementation"); } } else { log.info("No QAA level found. Set to default level " + EaafConstants.EIDAS_LOA_LOW); authData.setEidasLoa(EaafConstants.EIDAS_LOA_LOW); } } private void setFlagForeigner(final AuthenticationData authData, final IAuthProcessDataContainer authProcessData) { // TODO: change to new eIDAS-token attribute identifier if (authProcessData .getGenericDataFromSession(PvpAttributeDefinitions.EID_STORK_TOKEN_NAME) != null) { log.debug("Find PVP-Attr: " + PvpAttributeDefinitions.EID_STORK_TOKEN_FRIENDLY_NAME + " --> Set 'isForeigner' flag to TRUE"); authData.setForeigner(true); } else { authData.setForeigner(authProcessData.isForeigner()); } } /** * Build authentication data by using information from citizen-card or * mobile-phone signature This builder uses IdentityLink, AuthBlock, full MIS * mandate as input information. * * @param pendingReq current pendingRequest * @return {@link IAuthData} but never null * @throws EaafException In case of an error */ @Deprecated @NonNull protected abstract IAuthData buildDeprecatedAuthData(IRequest pendingReq) throws EaafException; @Deprecated protected void generateDeprecatedBasicAuthData(final AuthenticationData authData, final IRequest pendingReq, final IAuthProcessDataContainer authProcessData) throws EaafBuilderException, EaafConfigurationException, XPathException, DOMException, EaafParserException, EaafAuthenticationException { if (authProcessData.getGenericSessionDataStorage() != null && !authProcessData.getGenericSessionDataStorage().isEmpty()) { includedToGenericAuthData = authProcessData.getGenericSessionDataStorage().keySet(); } else { includedToGenericAuthData = new ArrayList<>(); } // #################################################### // set general authData info's authData.setAuthenticationIssuer(pendingReq.getAuthUrl()); authData.setSsoSession(pendingReq.needSingleSignOnFunctionality()); authData.setBaseIdTransferRestrication( pendingReq.getServiceProviderConfiguration().hasBaseIdTransferRestriction()); // #################################################### // parse user info's from identityLink IIdentityLink idlFromPvpAttr = null; final IIdentityLink identityLink = authProcessData.getIdentityLink(); if (identityLink != null) { parseBasicUserInfosFromIdl(authData, identityLink, includedToGenericAuthData); } else { // identityLink is not direct in MOASession final String pvpAttrIdl = authProcessData .getGenericDataFromSession(PvpAttributeDefinitions.EID_IDENTITY_LINK_NAME, String.class); // find PVP-Attr. which contains the IdentityLink if (StringUtils.isNotEmpty(pvpAttrIdl)) { log.debug("Find PVP-Attr: " + PvpAttributeDefinitions.EID_IDENTITY_LINK_FRIENDLY_NAME + " --> Parse basic user info's from that attribute."); InputStream idlStream = null; try { idlStream = new ByteArrayInputStream(Base64Utils.decodeFromString(pvpAttrIdl)); idlFromPvpAttr = new SimpleIdentityLinkAssertionParser(idlStream).parseIdentityLink(); parseBasicUserInfosFromIdl(authData, idlFromPvpAttr, includedToGenericAuthData); // set identitylink into AuthProcessData authProcessData.setIdentityLink(idlFromPvpAttr); } catch (final EaafParserException e) { log.warn("Received IdentityLink is not valid", e); } catch (final Exception e) { log.warn("Received IdentityLink is not valid", e); } finally { try { includedToGenericAuthData.remove(PvpAttributeDefinitions.EID_IDENTITY_LINK_NAME); if (idlStream != null) { idlStream.close(); } } catch (final IOException e) { log.warn("Close InputStream FAILED.", e); } } } // if no basic user info's are set yet, parse info's single PVP-Attributes if (StringUtils.isEmpty(authData.getFamilyName())) { log.debug( "No IdentityLink found or not parseable --> Parse basic user info's from single PVP-Attributes."); authData.setFamilyName(authProcessData .getGenericDataFromSession(PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, String.class)); authData.setGivenName(authProcessData .getGenericDataFromSession(PvpAttributeDefinitions.GIVEN_NAME_NAME, String.class)); authData.setDateOfBirth(authProcessData .getGenericDataFromSession(PvpAttributeDefinitions.BIRTHDATE_NAME, String.class)); authData.setIdentificationValue(authProcessData .getGenericDataFromSession(PvpAttributeDefinitions.EID_SOURCE_PIN_NAME, String.class)); authData.setIdentificationType(authProcessData.getGenericDataFromSession( PvpAttributeDefinitions.EID_SOURCE_PIN_TYPE_NAME, String.class)); // remove corresponding keys from genericSessionData if exists includedToGenericAuthData.remove(PvpAttributeDefinitions.PRINCIPAL_NAME_NAME); includedToGenericAuthData.remove(PvpAttributeDefinitions.GIVEN_NAME_NAME); includedToGenericAuthData.remove(PvpAttributeDefinitions.BIRTHDATE_NAME); includedToGenericAuthData.remove(PvpAttributeDefinitions.EID_SOURCE_PIN_NAME); includedToGenericAuthData.remove(PvpAttributeDefinitions.EID_SOURCE_PIN_TYPE_NAME); } } if (authData.getIdentificationType() != null && !authData.getIdentificationType().equals(EaafConstants.URN_PREFIX_BASEID)) { log.trace("IdentificationType is not a baseID --> clear it. "); authData.setBpk(authData.getIdentificationValue()); authData.setBpkType(authData.getIdentificationType()); authData.setIdentificationValue(null); authData.setIdentificationType(null); } // #################################################### // set QAA level setQaaLevel(authData, authProcessData); // #################################################### // set isForeigner flag setFlagForeigner(authData, authProcessData); // #################################################### // set citizen country-code setCitizenCountryCode(authData, authProcessData); // #################################################### // set bPK and IdentityLink final String pvpBpkValue = getBpkValueFromPvpAttribute(authProcessData); final String pvpBpkTypeAttr = getBpkTypeFromPvpAttribute(authProcessData); final Pair pvpEncBpkAttr = getEncryptedBpkFromPvpAttribute(authProcessData, authData, pendingReq.getServiceProviderConfiguration()); // check if a unique ID for this citizen exists if (StringUtils.isEmpty(authData.getIdentificationValue()) && StringUtils.isEmpty(pvpBpkValue) && StringUtils.isEmpty(authData.getBpk()) && pvpEncBpkAttr == null) { log.info( "Can not build authData, because session include no bPK, encrypted bPK or baseID"); throw new EaafBuilderException("builder.08", new Object[] { "No " + PvpAttributeDefinitions.BPK_FRIENDLY_NAME + " or " + PvpAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME + " or " + PvpAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME }, "No " + PvpAttributeDefinitions.BPK_FRIENDLY_NAME + " or " + PvpAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME + " or " + PvpAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME); } // check if bPK already added to AuthData matches OA if (StringUtils.isNotEmpty(authData.getBpk()) && matchsReceivedBpkToOnlineApplication( pendingReq.getServiceProviderConfiguration(), authData.getBpkType())) { log.debug("Correct bPK is already included in AuthData."); // check if bPK received by PVP-Attribute matches OA } else if (StringUtils.isNotEmpty(pvpBpkValue) && matchsReceivedBpkToOnlineApplication( pendingReq.getServiceProviderConfiguration(), pvpBpkTypeAttr)) { log.debug("Receive correct bPK from PVP-Attribute"); authData.setBpk(pvpBpkValue); authData.setBpkType(pvpBpkTypeAttr); // baseID is in AuthSesson --> calculate bPK directly } else if (StringUtils.isNotEmpty(authData.getIdentificationValue())) { log.debug("Citizen baseID is in AuthSession --> calculate bPK from this."); final Pair result = buildOAspecificbPK(pendingReq, authData); authData.setBpk(result.getFirst()); authData.setBpkType(result.getSecond()); // check if decrypted bPK exists } else if (pvpEncBpkAttr != null) { log.debug("Receive bPK as encrypted bPK and decryption was possible."); authData.setBpk(pvpEncBpkAttr.getFirst()); authData.setBpkType(pvpEncBpkAttr.getSecond()); // ask SZR to get bPK } else { String notValidbPK = authData.getBpk(); String notValidBpkType = authData.getBpkType(); if (StringUtils.isEmpty(notValidbPK) && StringUtils.isEmpty(notValidBpkType)) { notValidbPK = pvpBpkValue; notValidBpkType = pvpBpkTypeAttr; if (StringUtils.isEmpty(notValidbPK) && StringUtils.isEmpty(notValidBpkType)) { log.error("No bPK in AuthSession. THIS error should not occur any more."); throw new NullPointerException( "No bPK in AuthSession. THIS error should not occur any more."); } } final Pair baseIdFromSzr = getbaseIdFromSzr(authData, notValidbPK, notValidBpkType); if (baseIdFromSzr != null) { log.info("Receive citizen baseID from SRZ. Authentication can be completed"); authData.setIdentificationValue(baseIdFromSzr.getFirst()); authData.setIdentificationType(baseIdFromSzr.getSecond()); final Pair result = buildOAspecificbPK(pendingReq, authData); authData.setBpk(result.getFirst()); authData.setBpkType(result.getSecond()); } else { log.warn( "Can not build authData, because moaSession include no valid bPK, encrypted bPK or sourceID"); throw new EaafBuilderException("builder.13", new Object[] { pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier() }, "No valid " + PvpAttributeDefinitions.BPK_FRIENDLY_NAME + " or " + PvpAttributeDefinitions.EID_SOURCE_PIN_FRIENDLY_NAME + " or " + PvpAttributeDefinitions.ENC_BPK_LIST_FRIENDLY_NAME); } } // build IdentityLink if (authProcessData.getIdentityLink() != null) { authData .setIdentityLink(buildOAspecificIdentityLink(pendingReq.getServiceProviderConfiguration(), authProcessData.getIdentityLink(), authData.getBpk(), authData.getBpkType())); } else { log.info("Can NOT set IdentityLink. Msg: No IdentityLink found"); } } // extract a encrypted bPK from PVP attrobute @Deprecated protected abstract Pair getEncryptedBpkFromPvpAttribute( IAuthProcessDataContainer authProcessDataContainer, AuthenticationData authData, ISpConfiguration spConfig) throws EaafBuilderException; // request baseId from SRZ @Deprecated protected abstract Pair getbaseIdFromSzr(AuthenticationData authData, String notValidBpk, String notValidBpkType); @Deprecated protected Pair buildOAspecificbPK(final IRequest pendingReq, final AuthenticationData authData) throws EaafBuilderException { final ISpConfiguration oaParam = pendingReq.getServiceProviderConfiguration(); final String baseID = authData.getIdentificationValue(); final String baseIdType = authData.getIdentificationType(); Pair sectorSpecId = null; if (EaafConstants.URN_PREFIX_BASEID.equals(baseIdType)) { // SAML1 legacy target parameter work-around final String spTargetId = oaParam.getAreaSpecificTargetIdentifier(); log.debug("Use OA target identifier '" + spTargetId + "' from configuration"); new BpkBuilder(); // calculate sector specific unique identifier sectorSpecId = BpkBuilder.generateAreaSpecificPersonIdentifier(baseID, spTargetId); } else { log.error( "!!!baseID-element does not include a baseID. This should not be happen any more!!!"); sectorSpecId = Pair.newInstance(baseID, baseIdType); } log.trace("Authenticate user with bPK:" + sectorSpecId.getFirst() + " Type:" + sectorSpecId.getSecond()); return sectorSpecId; } @Deprecated protected IIdentityLink buildOAspecificIdentityLink(final ISpConfiguration spConfig, final IIdentityLink idl, final String bpk, final String bpkType) throws EaafConfigurationException, XPathException, DOMException, EaafParserException { if (spConfig.hasBaseIdTransferRestriction()) { log.debug("SP: " + spConfig.getUniqueIdentifier() + " has baseId transfer restriction. Remove baseId from IDL ..."); final Element idlassertion = idl.getSamlAssertion(); // set bpk/wpbk; final Node prIdentification = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH); prIdentification.getFirstChild().setNodeValue(bpk); // set bkp/wpbk type final Node prIdentificationType = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_IDENT_TYPE_XPATH); prIdentificationType.getFirstChild().setNodeValue(bpkType); final SimpleIdentityLinkAssertionParser idlparser = new SimpleIdentityLinkAssertionParser(idlassertion); return idlparser.parseIdentityLink(); } else { return idl; } } /** * Check a bPK-Type against a Service-Provider configuration
* If bPK-Type is null the result is false. * * @param oaParam Service-Provider configuration, never null * @param bpkType bPK-Type to check * @return true, if bPK-Type matchs to Service-Provider configuration, otherwise * false */ @Deprecated protected boolean matchsReceivedBpkToOnlineApplication(final ISpConfiguration oaParam, final String bpkType) { return oaParam.getAreaSpecificTargetIdentifier().equals(bpkType); } /** * Parse information from an IdentityLink into AuthData object. * * @param authData current authentication data * @param identityLink User's identityLink * @param includedGenericSessionData Generic AuthSession Data from PVP * attributes */ @Deprecated private void parseBasicUserInfosFromIdl(final AuthenticationData authData, final IIdentityLink identityLink, final Collection includedGenericSessionData) { authData.setIdentificationValue(identityLink.getIdentificationValue()); authData.setIdentificationType(identityLink.getIdentificationType()); /* * GivenNames and FamilyNames with simple Apostrophe were escaped with ' in * IdentityLinkParser since 5 years. This feature was bug-fix for an SL1.0 * AuthBlock problem. However, the authentication attributes (SAML2, eIDAS, * OpenID-Connect) also includes this escaped values, but there it is not * neccesary. We fix this problem in 3.4.3, but the fix can be deactivated for * dependency reasons. */ if (basicConfig.getBasicConfigurationBoolean(CONFIG_PROP_ENABLE_IDL_ATTRIBUTE_ESCAPEING, false)) { authData.setGivenName(identityLink.getGivenName().replaceAll("'", "'")); authData.setFamilyName(identityLink.getFamilyName().replaceAll("'", "'")); } else { authData.setGivenName(identityLink.getGivenName()); authData.setFamilyName(identityLink.getFamilyName()); } authData.setDateOfBirth(identityLink.getDateOfBirth()); // remove corresponding keys from genericSessionData if exists includedGenericSessionData.remove(PvpAttributeDefinitions.PRINCIPAL_NAME_NAME); includedGenericSessionData.remove(PvpAttributeDefinitions.GIVEN_NAME_NAME); includedGenericSessionData.remove(PvpAttributeDefinitions.BIRTHDATE_NAME); includedGenericSessionData.remove(PvpAttributeDefinitions.EID_SOURCE_PIN_NAME); includedGenericSessionData.remove(PvpAttributeDefinitions.EID_SOURCE_PIN_TYPE_NAME); } /** * Get bPK from PVP Attribute 'BPK_NAME', which could be exist in MOASession as * 'GenericData'.
* *
   * session.getGenericDataFromSession(PVPConstants.BPK_NAME, String.class)
   * 
* * @param session MOASession, but never null * @return bPK, which was received by PVP-Attribute, or null if no * attribute exists */ @Deprecated private String getBpkValueFromPvpAttribute(final IAuthProcessDataContainer session) { String pvpBpkValueAttr = session.getGenericDataFromSession(PvpAttributeDefinitions.BPK_NAME, String.class); if (StringUtils.isNotEmpty(pvpBpkValueAttr)) { // fix a wrong bPK-value prefix, which was used in some PVP Standardportal // implementations if (pvpBpkValueAttr.startsWith("bPK:")) { log.warn("Attribute " + PvpAttributeDefinitions.BPK_NAME + " contains a not standardize prefix! Staring attribute value correction process ..."); pvpBpkValueAttr = pvpBpkValueAttr.substring("bPK:".length()); } final String[] spitted = pvpBpkValueAttr.split(":"); if (spitted.length == 2) { log.debug("Find PVP-Attr: " + PvpAttributeDefinitions.BPK_FRIENDLY_NAME); return spitted[1]; } else if (spitted.length > 2) { log.warn("Attribute " + PvpAttributeDefinitions.BPK_NAME + " has a wrong encoding and can NOT be USED!" + " Value:" + pvpBpkValueAttr); return null; } else { log.debug("Find PVP-Attr: " + PvpAttributeDefinitions.BPK_FRIENDLY_NAME + " without prefix. Use it as it is"); return spitted[0]; } } return null; } /** * Get bPK-Type from PVP Attribute 'EID_SECTOR_FOR_IDENTIFIER_NAME', which could * be exist in MOASession as 'GenericData'.
* *
   * session.getGenericDataFromSession(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME, String.class)
   * 
* * @param session MOASession, but never null * @return bPKType, which was received by PVP-Attribute, or null if * no attribute exists */ @Deprecated private String getBpkTypeFromPvpAttribute(final IAuthProcessDataContainer session) { final String pvpBpkTypeAttr = session.getGenericDataFromSession( PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME, String.class); if (StringUtils.isNotEmpty(pvpBpkTypeAttr)) { // //fix a wrong bPK-Type encoding, which was used in some PVP Standardportal // implementations // if (pvpbPKTypeAttr.startsWith(EAAFConstants.URN_PREFIX_CDID) && // !pvpbPKTypeAttr.substring(EAAFConstants.URN_PREFIX_CDID.length(), // EAAFConstants.URN_PREFIX_CDID.length() + 1).equals("+")) { // log.warn("Receive uncorrect encoded bBKType attribute " + pvpbPKTypeAttr + " // Starting // attribute value correction ... "); // pvpbPKTypeAttr = EAAFConstants.URN_PREFIX_CDID + "+" + // pvpbPKTypeAttr.substring(EAAFConstants.URN_PREFIX_CDID.length() + 1); // // } log.debug( "Find PVP-Attr: " + PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME); return pvpBpkTypeAttr; } return null; /* * INFO: This code could be used to extract the bPKType from * 'PVPConstants.BPK_NAME', because the prefix of BPK_NAME attribute contains * the postfix of the bPKType * * Now, all PVP Standardportals should be able to send * 'EID_SECTOR_FOR_IDENTIFIER' PVP attributes */ // String pvpbPKValueAttr = // session.getGenericDataFromSession(PVPConstants.BPK_NAME, // String.class); // String[] spitted = pvpbPKValueAttr.split(":"); // if (MiscUtil.isEmpty(authData.getBPKType())) { // Logger.debug("PVP assertion contains NO bPK/wbPK target attribute. " + // "Starting target extraction from bPK/wbPK prefix ..."); // //exract bPK/wbPK type from bpk attribute value prefix if type is // //not transmitted as single attribute // Pattern pattern = Pattern.compile("[a-zA-Z]{2}(-[a-zA-Z]+)?"); // Matcher matcher = pattern.matcher(spitted[0]); // if (matcher.matches()) { // //find public service bPK // authData.setBPKType(Constants.URN_PREFIX_CDID + "+" + spitted[0]); // Logger.debug("Found bPK prefix. Set target to " + authData.getBPKType()); // // } else { // //find business service wbPK // authData.setBPKType(Constants.URN_PREFIX_WBPK+ "+" + spitted[0]); // Logger.debug("Found wbPK prefix. Set target to " + authData.getBPKType()); // // } // } } }