/* * Copyright 2014 Federal Chancellery Austria * MOA-ID has been developed in a cooperation between BRZ, the Federal * Chancellery Austria - ICT staff unit, and Graz University of Technology. * * Licensed under the EUPL, Version 1.1 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: * http://www.osor.eu/eupl/ * * 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.egovernment.moa.id.auth.builder; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.security.PrivateKey; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.w3c.dom.DOMException; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; 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.IAuthData; 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.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.builder.AbstractAuthenticationDataBuilder; import at.gv.egiz.eaaf.core.impl.idp.auth.builder.BPKBuilder; import at.gv.egiz.eaaf.core.impl.utils.XPathUtils; import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants; import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionWrapper; import at.gv.egovernment.moa.id.auth.exception.BuildException; import at.gv.egovernment.moa.id.auth.exception.DynamicOABuildException; import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser; import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; import at.gv.egovernment.moa.id.commons.api.data.ExtendedSAMLAttribute; import at.gv.egovernment.moa.id.commons.api.data.IAuthenticationSession; import at.gv.egovernment.moa.id.commons.api.data.IMISMandate; import at.gv.egovernment.moa.id.commons.api.data.IVerifiyXMLSignatureResponse; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants; import at.gv.egovernment.moa.id.commons.db.dao.session.OASessionStore; import at.gv.egovernment.moa.id.config.auth.OAAuthParameterDecorator; import at.gv.egovernment.moa.id.data.AuthenticationRoleFactory; import at.gv.egovernment.moa.id.data.MISMandate; import at.gv.egovernment.moa.id.data.MOAAuthenticationData; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage; import at.gv.egovernment.moa.id.util.IdentityLinkReSigner; import at.gv.egovernment.moa.id.util.LoALevelMapper; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.Base64Utils; import at.gv.egovernment.moa.util.Constants; import at.gv.egovernment.moa.util.MiscUtil; import at.gv.util.client.szr.SZRClient; import at.gv.util.config.EgovUtilPropertiesConfiguration; import at.gv.util.wsdl.szr.SZRException; import at.gv.util.xsd.szr.PersonInfoType; import iaik.x509.X509Certificate; /** * @author tlenz * */ @Service("AuthenticationDataBuilder") public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder { public static final String CONFIGURATION_PROP_FOREIGN_BPK_ENC_KEYS = "configuration.foreignsectors.pubkey"; @Autowired private IAuthenticationSessionStoreage authenticatedSessionStorage; @Autowired protected AuthConfiguration authConfig; @Autowired protected LoALevelMapper loaLevelMapper; private Map encKeyMap = new HashMap(); @PostConstruct private void initialize() { Map pubKeyMap = authConfig.getBasicMOAIDConfigurationWithPrefix(CONFIGURATION_PROP_FOREIGN_BPK_ENC_KEYS); for (Entry el : pubKeyMap.entrySet()) { try { encKeyMap.put(el.getKey(), new X509Certificate(Base64Utils.decode(el.getValue(), false))); Logger.info("Load foreign bPK encryption certificate for sector: " + el.getKey()); } catch (Exception e) { if (Logger.isDebugEnabled()) Logger.warn("Can NOT load foreign bPK encryption certificate for sector: " + el.getKey(), e); else Logger.info("Can NOT load foreign bPK encryption certificate for sector: " + el.getKey()); } } } @Override public IAuthData buildAuthenticationData(IRequest pendingReq) throws EAAFAuthenticationException { try { return buildAuthenticationData(pendingReq, pendingReq.getSessionData(AuthenticationSessionWrapper.class), pendingReq.getServiceProviderConfiguration(OAAuthParameterDecorator.class)); } catch (ConfigurationException | BuildException | WrongParametersException | DynamicOABuildException | EAAFBuilderException e) { Logger.warn("Can not build authentication data from session information"); throw new EAAFAuthenticationException("builder.11", new Object[]{e.getMessage()}, e); } } private IAuthData buildAuthenticationData(IRequest pendingReq, IAuthenticationSession session, IOAAuthParameters oaParam) throws ConfigurationException, BuildException, WrongParametersException, DynamicOABuildException, EAAFBuilderException { MOAAuthenticationData authdata = null; //only needed for SAML1 legacy support try { //check if SAML1 authentication module is in Classpath Class saml1RequstTemplate = Class.forName("at.gv.egovernment.moa.id.protocols.saml1.SAML1RequestImpl"); //IAuthData saml1authdata = (IAuthData) Class.forName("at.gv.egovernment.moa.id.protocols.saml1.SAML1AuthenticationData").newInstance(); IAuthData saml1authdata = (IAuthData) Class.forName("at.gv.egovernment.moa.id.protocols.saml1.SAML1AuthenticationData").getConstructor(LoALevelMapper.class).newInstance(loaLevelMapper); if (saml1RequstTemplate != null && saml1RequstTemplate.isInstance(pendingReq)) { //request is SAML1 --> invoke SAML1 protocol specific methods if (session.getExtendedSAMLAttributesOA() == null) { saml1authdata.getClass().getMethod("setExtendedSAMLAttributesOA", List.class).invoke(saml1authdata, new ArrayList()); } else { saml1authdata.getClass().getMethod("setExtendedSAMLAttributesOA", List.class).invoke(saml1authdata, session.getExtendedSAMLAttributesOA()); } authdata = (MOAAuthenticationData) saml1authdata; } else { authdata = new MOAAuthenticationData(loaLevelMapper); } } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | java.lang.SecurityException ex) { authdata = new MOAAuthenticationData(loaLevelMapper); } OASessionStore activeOA = authenticatedSessionStorage.searchActiveOASSOSession(session, pendingReq.getSPEntityId(), pendingReq.requestedModule()); //reuse authentication information in case of service-provider reauthentication if (activeOA != null) { authdata.setSessionIndex(activeOA.getAssertionSessionID()); authdata.setNameID(activeOA.getUserNameID()); authdata.setNameIDFormat(activeOA.getUserNameIDFormat()); } //TODO: move to eIDAS-Code in case of ISA1.18 action is enabled for eIDAS //build OA dynamically from STROK request if this OA is used as STORK<->PVP gateway if (oaParam.isSTORKPVPGateway()) oaParam = DynamicOAAuthParameterBuilder.buildFromAuthnRequest(oaParam, pendingReq); Boolean isMinimalFrontChannelResp = pendingReq.getRawData( MOAIDAuthConstants.DATAID_INTERFEDERATION_MINIMAL_FRONTCHANNEL_RESP, Boolean.class); if (isMinimalFrontChannelResp != null && isMinimalFrontChannelResp) { //only set minimal response attributes authdata.setQAALevel( pendingReq.getRawData(MOAIDAuthConstants.DATAID_INTERFEDERATION_QAALEVEL, String.class)); authdata.setBPK( pendingReq.getRawData(MOAIDAuthConstants.DATAID_INTERFEDERATION_NAMEID, String.class)); } else { //build AuthenticationData from MOASession buildAuthDataFormMOASession(authdata, session, oaParam, pendingReq); } return authdata; } private void buildAuthDataFormMOASession(MOAAuthenticationData authData, IAuthenticationSession session, IOAAuthParameters oaParam, IRequest protocolRequest) throws BuildException, ConfigurationException, EAAFBuilderException { try { //generate basic authentication data generateBasicAuthData(authData, protocolRequest, session); //set Austrian eID demo-mode flag authData.setIseIDNewDemoMode(Boolean.parseBoolean( oaParam.getConfigurationValue( MOAIDConfigurationConstants.SERVICE_AUTH_AUSTRIAN_EID_DEMO_MODE, String.valueOf(false)))); if (authData.isIseIDNewDemoMode()) { Logger.info("Demo-mode for 'New Austrian eID' is active. Set 'BaseIDTransferRestrication' to true"); authData.setBaseIDTransferRestrication(true); } // #### generate MOA-ID specific authentication data ###### //set BKU URL includedToGenericAuthData.remove(PVPConstants.EID_CCS_URL_NAME); if (MiscUtil.isNotEmpty(session.getBkuURL())) authData.setBkuURL(session.getBkuURL()); else authData.setBkuURL(session.getGenericDataFromSession(PVPConstants.EID_CCS_URL_NAME, String.class)); //TODO: fully switch from STORK QAA to eIDAS LoA //#################################################### //set QAA level if (MiscUtil.isNotEmpty(authData.getEIDASQAALevel())) { Logger.debug("Find eIDAS LoA. Map it to STORK QAA"); authData.setQAALevel(loaLevelMapper.mapeIDASQAAToSTORKQAA(authData.getEIDASQAALevel())); } else { Logger.info("Find NO eIDAS Loa. Starting STORK QAA processing as backup ... "); includedToGenericAuthData.remove(PVPConstants.EID_CITIZEN_QAA_LEVEL_NAME); String currentLoA = null; if (MiscUtil.isNotEmpty(session.getQAALevel())) currentLoA = session.getQAALevel(); else { currentLoA = session.getGenericDataFromSession(PVPConstants.EID_CITIZEN_QAA_LEVEL_NAME, String.class); if (MiscUtil.isNotEmpty(currentLoA)) { Logger.debug("Find PVP-Attr '" + PVPConstants.EID_CITIZEN_QAA_LEVEL_FRIENDLY_NAME + "':" + currentLoA + " --> Parse QAA-Level from that attribute."); } } if (MiscUtil.isNotEmpty(currentLoA)) { if (currentLoA.startsWith(PVPConstants.STORK_QAA_PREFIX)) { authData.setQAALevel(currentLoA); authData.seteIDASLoA(loaLevelMapper.mapSTORKQAAToeIDASQAA(currentLoA)); } else if (currentLoA.startsWith(EAAFConstants.EIDAS_LOA_PREFIX)) { authData.setQAALevel(loaLevelMapper.mapeIDASQAAToSTORKQAA(currentLoA)); authData.seteIDASLoA(currentLoA); } else { Logger.debug("Found PVP SecClass. QAA mapping process starts ... "); String mappedStorkQAA = loaLevelMapper.mapSecClassToQAALevel(currentLoA); if (MiscUtil.isNotEmpty(mappedStorkQAA)) { authData.setQAALevel(mappedStorkQAA); authData.seteIDASLoA(loaLevelMapper.mapSTORKQAAToeIDASQAA(mappedStorkQAA)); } } } } //if no QAA level is set in MOASession then set default QAA level if (MiscUtil.isEmpty(authData.getEIDASQAALevel())) { Logger.info("No QAA level found. Set to default level " + EAAFConstants.EIDAS_LOA_LOW); authData.setQAALevel(PVPConstants.STORK_QAA_PREFIX + "1"); authData.seteIDASLoA(EAAFConstants.EIDAS_LOA_LOW); } //#################################################### //set signer certificate includedToGenericAuthData.remove(PVPConstants.EID_SIGNER_CERTIFICATE_NAME); if (session.getEncodedSignerCertificate() != null) authData.setSignerCertificate(session.getEncodedSignerCertificate()); else { String pvpAttrSignerCert = session.getGenericDataFromSession(PVPConstants.EID_SIGNER_CERTIFICATE_NAME, String.class); if (MiscUtil.isNotEmpty(pvpAttrSignerCert)) { Logger.debug("Find PVP-Attr: " + PVPConstants.EID_SIGNER_CERTIFICATE_FRIENDLY_NAME); try { authData.setSignerCertificate(Base64Utils.decode(pvpAttrSignerCert, false)); } catch (IOException e) { Logger.error("SignerCertificate received via federated IDP is NOT valid", e); } } else Logger.info("NO SignerCertificate in MOASession."); } //#################################################### //set authBlock includedToGenericAuthData.remove(PVPConstants.EID_AUTH_BLOCK_NAME); if (MiscUtil.isNotEmpty(session.getAuthBlock())) { authData.setAuthBlock(session.getAuthBlock()); } else { String pvpAttrAuthBlock = session.getGenericDataFromSession(PVPConstants.EID_AUTH_BLOCK_NAME, String.class); if (MiscUtil.isNotEmpty(pvpAttrAuthBlock)) { Logger.debug("Find PVP-Attr: " + PVPConstants.EID_AUTH_BLOCK_FRIENDLY_NAME); try { byte[] authBlock = Base64Utils.decode(pvpAttrAuthBlock, false); authData.setAuthBlock(new String(authBlock, "UTF-8")); } catch (IOException e) { Logger.error("AuthBlock received via federated IDP is NOT valid", e); } } else Logger.info("NO AuthBlock in MOASession."); } //#################################################### //set max. SSO session time includedToGenericAuthData.remove(AuthenticationSessionStorageConstants.FEDERATION_RESPONSE_VALIDE_TO); Date validToFromFederatedIDP = session.getGenericDataFromSession( AuthenticationSessionStorageConstants.FEDERATION_RESPONSE_VALIDE_TO, Date.class); if (validToFromFederatedIDP != null) { authData.setSsoSessionValidTo(validToFromFederatedIDP); Logger.debug("Use idToken validTo periode from federated IDP response."); } else { if (authData.isSsoSession()) { long maxSSOSessionTime = authConfig.getSSOCreatedTimeOut() * 1000; Date ssoSessionValidTo = new Date(session.getSessionCreated().getTime() + maxSSOSessionTime); authData.setSsoSessionValidTo(ssoSessionValidTo); } else { //set valid to 5 min Date ssoSessionValidTo = new Date(new Date().getTime() + 5 * 60 * 1000); authData.setSsoSessionValidTo(ssoSessionValidTo); } } //mandate functionality IMISMandate misMandate = null; if (session.isMandateUsed()) { //#################################################### //set Mandate reference value includedToGenericAuthData.remove(PVPConstants.MANDATE_REFERENCE_VALUE_NAME); if (MiscUtil.isNotEmpty(session.getMandateReferenceValue())) authData.setMandateReferenceValue(session.getMandateReferenceValue()); else { String pvpMandateRefAttr = session.getGenericDataFromSession(PVPConstants.MANDATE_REFERENCE_VALUE_NAME, String.class); if (MiscUtil.isNotEmpty(pvpMandateRefAttr)) { authData.setMandateReferenceValue(pvpMandateRefAttr); Logger.debug("Find PVP-Attr: " + PVPConstants.MANDATE_REFERENCE_VALUE_FRIENDLY_NAME); } } /* TODO: Support SSO Mandate MODE! * Insert functionality to translate mandates in case of SSO */ //#################################################### //set Full-mandate misMandate = session.getMISMandate(); if (misMandate != null ) { //set MIS mandate to authdata authData.setMISMandate(misMandate); authData.setUseMandate(session.isMandateUsed()); } else { String pvpFullMandateAttr = session.getGenericDataFromSession( PVPConstants.MANDATE_FULL_MANDATE_NAME, String.class); //check if full-mandate is available as PVP attribute if (MiscUtil.isNotEmpty(pvpFullMandateAttr)) { Logger.debug("Find PVP-Attr: " + PVPConstants.MANDATE_FULL_MANDATE_FRIENDLY_NAME); try { byte[] mandate = Base64Utils.decode(pvpFullMandateAttr, false); misMandate = new MISMandate(); misMandate.setMandate(mandate); //read Organwalter OID String pvpRepOIDAttr = session.getGenericDataFromSession(PVPConstants.MANDATE_PROF_REP_OID_NAME, String.class); if (MiscUtil.isNotEmpty(pvpRepOIDAttr)) { misMandate.setProfRep(pvpRepOIDAttr); Logger.debug("Find PVP-Attr: " + PVPConstants.MANDATE_PROF_REP_OID_NAME); } //read Organwalter bPK from full-mandate NodeList mandateElements = misMandate.getMandateDOM().getChildNodes(); for (int i=0; i Use single PVP attributes for mandate information."); //check if ELGA mandates exists String mandateType = session.getGenericDataFromSession(PVPConstants.MANDATE_TYPE_NAME, String.class); if (MiscUtil.isNotEmpty(mandateType)) { //switch to mandate-mode for authdata generation, because mandate-information // is directly included in MOA-Session as PVP attributes Logger.info("AuthDataBuilder find directly included 'MandateType' PVP-attribute." + " --> Switch to mandate-mode for authdata generation."); authData.setUseMandate(true); } } } //remove PVP attributes with mandate information, because full-mandate exists if (authData.getMISMandate() != null) { includedToGenericAuthData.remove(PVPConstants.MANDATE_FULL_MANDATE_NAME); includedToGenericAuthData.remove(PVPConstants.MANDATE_TYPE_NAME); includedToGenericAuthData.remove(PVPConstants.MANDATE_LEG_PER_FULL_NAME_NAME); includedToGenericAuthData.remove(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_NAME); includedToGenericAuthData.remove(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME); includedToGenericAuthData.remove(PVPConstants.MANDATE_NAT_PER_FAMILY_NAME_NAME); includedToGenericAuthData.remove(PVPConstants.MANDATE_NAT_PER_GIVEN_NAME_NAME); includedToGenericAuthData.remove(PVPConstants.MANDATE_NAT_PER_BIRTHDATE_NAME); includedToGenericAuthData.remove(PVPConstants.MANDATE_NAT_PER_BPK_NAME); includedToGenericAuthData.remove(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_NAME); includedToGenericAuthData.remove(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_TYPE_NAME); includedToGenericAuthData.remove(PVPConstants.MANDATE_PROF_REP_DESC_NAME); includedToGenericAuthData.remove(PVPConstants.MANDATE_PROF_REP_OID_NAME); } } //#################################################### // set bPK and IdentityLink for Organwalter --> // Organwalter has a special bPK is received from MIS if (authData.isUseMandate() && session.isOW() && misMandate != null && MiscUtil.isNotEmpty(misMandate.getOWbPK())) { //TODO: if full-mandate is removed in OPB --> OWbPK functionality needs an update!!! authData.setBPK(misMandate.getOWbPK()); authData.setBPKType(Constants.URN_PREFIX_CDID + "+" + "OW"); Logger.trace("Authenticated User is OW: " + misMandate.getOWbPK()); //set bPK and IdenityLink for all other Logger.debug("User is an OW. Set original IDL into authdata ... "); authData.setIdentityLink(session.getIdentityLink()); } //################################################################### //set PVP role attribute (implemented for ISA 1.18 action) includedToGenericAuthData.remove(PVPConstants.ROLES_NAME); String pvpAttrRoles = session.getGenericDataFromSession(PVPConstants.ROLES_NAME, String.class); if (MiscUtil.isNotEmpty(pvpAttrRoles)) { List roles = Arrays.asList(pvpAttrRoles.split(";")); for (String role : roles) { authData.addAuthenticationRole(AuthenticationRoleFactory.buildFormPVPole(role)); } } //################################################################### //set PVP OU attribute (implemented for ISA 1.18 action) includedToGenericAuthData.remove(PVPConstants.OU_NAME); String pvpAttrOUName = session.getGenericDataFromSession(PVPConstants.OU_NAME, String.class); if (MiscUtil.isNotEmpty(pvpAttrOUName)) { authData.setPvpAttribute_OU(pvpAttrOUName); Logger.debug("Found PVP 'OU' attribute in response -> " + authData.getPvpAttribute_OU()); } //#################################################################### //parse AuthBlock signature-verification response //INFO: this parameters are only required for SAML1 auth. protocol IVerifiyXMLSignatureResponse verifyXMLSigResp = session.getXMLVerifySignatureResponse(); if (verifyXMLSigResp != null) { authData.setQualifiedCertificate(verifyXMLSigResp .isQualifiedCertificate()); authData.setPublicAuthority(verifyXMLSigResp.isPublicAuthority()); authData.setPublicAuthorityCode(verifyXMLSigResp .getPublicAuthorityCode()); } else { //set parameters in respect to QAA level Logger.info("No authBlock signature-verfication response found. Maybe IDP federation is in use."); if (PVPConstants.STORK_QAA_1_4.equals(authData.getQAALevel())) authData.setQualifiedCertificate(true); else authData.setQualifiedCertificate(false); authData.setPublicAuthority(false); } //build foreign bPKs generateForeignbPK(authData, oaParam.foreignbPKSectorsRequested()); if (Boolean.parseBoolean( oaParam.getConfigurationValue( MOAIDConfigurationConstants.SERVICE_AUTH_AUSTRIAN_EID_DEMO_MODE, String.valueOf(false)))) { Logger.info("Demo-Mode for Austrian eID is active. Post-Processing authData according the new requirements ... "); //build additional bPKs Logger.debug("Search for additional bPKs"); generateAdditonalbPK(authData, oaParam.additionalbPKSectorsRequested()); Logger.debug("Clearing identitylink ... "); authData.setIdentityLink(null); Logger.debug("Clearing authBlock ... "); authData.setAuthBlock(null); Logger.info("Post-Processing for Austrian eID finished"); } //#################################################################### //copy all generic authentication information, which are not processed before to authData Iterator copyInterator = includedToGenericAuthData.iterator(); while (copyInterator.hasNext()) { String elementKey = copyInterator.next(); try { authData.setGenericData(elementKey, session.getGenericDataFromSession(elementKey)); } catch (EAAFStorageException e) { Logger.warn("Can not add generic authData with key:" + elementKey, e); } } } catch (EAAFBuilderException e) { throw e; } catch (Throwable ex) { throw new BuildException("builder.00", new Object[]{ "AuthenticationData", ex.toString()}, ex); } } /** * @param authData * @param notValidbPK * @param notValidbPKType * @return */ @Override protected Pair getbaseIDFromSZR(AuthenticationData authData, String notValidbPK, String notValidbPKType) { try { EgovUtilPropertiesConfiguration eGovClientsConfig = authConfig.geteGovUtilsConfig(); if (eGovClientsConfig != null) { Logger.info("bPK in MOASession (bPK-Type:" + notValidbPKType + " does no match to Service-Provider configuration. --> Request SZR to get correct bPK."); SZRClient szrclient = new SZRClient(eGovClientsConfig); Logger.debug("Create SZR request to get baseID ... "); PersonInfoType personInfo = new PersonInfoType(); at.gv.util.xsd.szr.persondata.PhysicalPersonType person = new at.gv.util.xsd.szr.persondata.PhysicalPersonType(); personInfo.setPerson(person); at.gv.util.xsd.szr.persondata.PersonNameType name = new at.gv.util.xsd.szr.persondata.PersonNameType(); person.setName(name); at.gv.util.xsd.szr.persondata.IdentificationType idValue = new at.gv.util.xsd.szr.persondata.IdentificationType(); person.setIdentification(idValue); //set bPK or wbPK idValue.setValue(authData.getBPK()); idValue.setType(authData.getBPKType()); //set person information name.setGivenName(authData.getGivenName()); name.setFamilyName(authData.getFamilyName()); if (authData.getDateOfBirth() != null) person.setDateOfBirth(authData.getFormatedDateOfBirth()); //request szr and store baseID return Pair.newInstance(szrclient.getStammzahl(personInfo), Constants.URN_PREFIX_BASEID); } else { Logger.debug("No SZR clieht configuration found."); return null; } } catch (SZRException e) { Logger.warn("SZR connection FAILED. Interfederation SSO login not possible.", e); } catch (at.gv.util.ex.EgovUtilException e) { Logger.warn("SZR connection FAILED. Interfederation SSO login not possible.", e); } return null; } /** * Add encrypted bPKs from PVP Attribute 'ENC_BPK_LIST_NAME', which could be exist in * MOASession as 'GenericData'
session.getGenericDataFromSession(PVPConstants.ENC_BPK_LIST_NAME, String.class)
* to authData * * @param authProcessDataContainer MOASession, but never null * @param authData AuthenticationData DAO * @param spConfig Service-Provider configuration * * @return Pair which was received by PVP-Attribute and could be decrypted for this Service Provider, * or null if no attribute exists or can not decrypted * @throws ConfigurationException */ @Override protected Pair getEncryptedbPKFromPVPAttribute(IAuthProcessDataContainer authProcessDataContainer, AuthenticationData authData, ISPConfiguration spConfig) throws EAAFBuilderException { //set List of encrypted bPKs to authData DAO if (authData instanceof MOAAuthenticationData && spConfig instanceof IOAAuthParameters) { String pvpEncbPKListAttr = authProcessDataContainer.getGenericDataFromSession(PVPConstants.ENC_BPK_LIST_NAME, String.class); if (MiscUtil.isNotEmpty(pvpEncbPKListAttr)) { List encbPKList = Arrays.asList(pvpEncbPKListAttr.split(";")); ((MOAAuthenticationData) authData).setEncbPKList(encbPKList); //check if one of this encrypted bPK could be decrypt for this Service-Provider for (String fullEncbPK : encbPKList) { int index = fullEncbPK.indexOf("|"); if (index >= 0) { String encbPK = fullEncbPK.substring(index+1); String second = fullEncbPK.substring(0, index); int secIndex = second.indexOf("+"); if (secIndex >= 0) { String oaTargetId = spConfig.getAreaSpecificTargetIdentifier(); if (oaTargetId.startsWith(MOAIDAuthConstants.PREFIX_CDID)) { String publicServiceShortTarget = oaTargetId.substring(MOAIDAuthConstants.PREFIX_CDID.length()); if (publicServiceShortTarget.equals(second.substring(secIndex+1))) { Logger.debug("Found encrypted bPK for online-application " + spConfig.getUniqueIdentifier() + " Start decryption process ..."); PrivateKey privKey = ((IOAAuthParameters) spConfig).getBPKDecBpkDecryptionKey(); if (privKey != null) { try { String bPK = BPKBuilder.decryptBPK(encbPK, publicServiceShortTarget, privKey); if (MiscUtil.isNotEmpty(bPK)) { Logger.info("bPK decryption process finished successfully."); return Pair.newInstance(bPK, oaTargetId); } else { Logger.error("bPK decryption FAILED."); } } catch (EAAFBuilderException e) { Logger.error("bPK decryption FAILED.", e); } } else { Logger.info("bPK decryption FAILED, because no valid decryption key is found."); } } else { Logger.info("Found encrypted bPK but " + "encrypted bPK target does not match to online-application target"); } } else { Logger.info("Encrypted bPKs are only allowed for public services with prefix: " + MOAIDAuthConstants.PREFIX_CDID + " BUT oaTarget is " + oaTargetId); } } } } } } else Logger.warn("AuthData: " + authData.getClass().getName() + " or spConfig: " + spConfig.getClass().getName() + " are not MOAID data-objects"); return null; } @Override protected IIdentityLink buildOAspecificIdentityLink(ISPConfiguration spConfig, IIdentityLink idl, String bPK, String bPKType) throws EAAFConfigurationException, XPathException, DOMException, EAAFParserException { if (spConfig.hasBaseIdTransferRestriction()) { try { Element idlassertion = idl.getSamlAssertion(); //set bpk/wpbk; Node prIdentification = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH); prIdentification.getFirstChild().setNodeValue(bPK); //set bkp/wpbk type Node prIdentificationType = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_IDENT_TYPE_XPATH); prIdentificationType.getFirstChild().setNodeValue(bPKType); IdentityLinkAssertionParser idlparser = new IdentityLinkAssertionParser(idlassertion); IIdentityLink businessServiceIdl = idlparser.parseIdentityLink(); //resign IDL IdentityLinkReSigner identitylinkresigner = IdentityLinkReSigner.getInstance(); Element resignedilAssertion; if (authConfig.isIdentityLinkResigning()) { resignedilAssertion = identitylinkresigner.resignIdentityLink(businessServiceIdl.getSamlAssertion(), authConfig.getIdentityLinkResigningKey()); } else { resignedilAssertion = businessServiceIdl.getSamlAssertion(); } IdentityLinkAssertionParser resignedIDLParser = new IdentityLinkAssertionParser(resignedilAssertion); return resignedIDLParser.parseIdentityLink(); } catch (MOAIDException e) { Logger.warn("Can not build OA specific IDL. Reason: " + e.getMessage(), e); throw new EAAFParserException("TODO", null, e); } } else return idl; } @Override protected Pair buildOAspecificbPK(IRequest pendingReq, AuthenticationData authData) throws EAAFBuilderException { ISPConfiguration oaParam = pendingReq.getServiceProviderConfiguration(); String baseID = authData.getIdentificationValue(); String baseIDType = authData.getIdentificationType(); Pair sectorSpecId = null; if (Constants.URN_PREFIX_BASEID.equals(baseIDType)) { //SAML1 legacy target parameter work-around String oaTargetId = null; Class saml1RequstTemplate = null; try { saml1RequstTemplate = Class.forName("at.gv.egovernment.moa.id.protocols.saml1.SAML1RequestImpl"); if (saml1RequstTemplate != null && saml1RequstTemplate.isInstance(pendingReq)) { oaTargetId = (String) pendingReq.getClass().getMethod("getTarget").invoke(pendingReq); } } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | java.lang.SecurityException | InvocationTargetException | NoSuchMethodException ex) { } if (MiscUtil.isEmpty(oaTargetId)) { oaTargetId = oaParam.getAreaSpecificTargetIdentifier(); Logger.debug("Use OA target identifier '" + oaTargetId + "' from configuration"); } else Logger.info("Use OA target identifier '" + oaTargetId + "' from SAML1 request for bPK calculation"); //calculate sector specific unique identifier sectorSpecId = new BPKBuilder().generateAreaSpecificPersonIdentifier(baseID, oaTargetId); } else { Logger.fatal("!!!baseID-element does not include a baseID. This should not be happen any more!!!"); sectorSpecId = Pair.newInstance(baseID, baseIDType); } Logger.trace("Authenticate user with bPK:" + sectorSpecId.getFirst() + " Type:" + sectorSpecId.getSecond()); return sectorSpecId; } private void generateForeignbPK(MOAAuthenticationData authData, List foreignSectors) { if (foreignSectors != null && !foreignSectors.isEmpty()) { Logger.debug("Sectors for foreign bPKs are configurated. Starting foreign bPK generation ... "); for (String foreignSector : foreignSectors) { Logger.trace("Process sector: " + foreignSector + " ... "); if (encKeyMap.containsKey(foreignSector)) { try { String sector = null; //splitt sector into VKZ and target if (foreignSector.startsWith("wbpk")) { Logger.trace("Find foreign private sector " + foreignSector); sector = Constants.URN_PREFIX + ":" + foreignSector; } else { String[] split = foreignSector.split("+"); if (split.length != 2) { Logger.warn("Foreign sector: " + foreignSector + " looks WRONG. IGNORE IT!"); } else { Logger.trace("Find foreign public sector. VKZ: " + split[0] + " Target: " + split[1]); sector = Constants.URN_PREFIX_CDID + "+" + split[1]; } } if (sector != null) { Pair bpk = new BPKBuilder().generateAreaSpecificPersonIdentifier( authData.getIdentificationValue(), authData.getIdentificationType(), sector); String foreignbPK = BPKBuilder.encryptBPK(bpk.getFirst(), bpk.getSecond(), encKeyMap.get(foreignSector).getPublicKey()); authData.getEncbPKList().add("(" + foreignSector + "|" + foreignbPK + ")"); Logger.debug("Foreign bPK for sector: " + foreignSector + " created."); } } catch (Exception e) { Logger.warn("Foreign bPK generation FAILED for sector: " + foreignSector, e); } } else { Logger.info("NO encryption cerfificate FOUND in configuration for sector: " + foreignSector); Logger.info("Foreign bPK for sector: " + foreignSector + " is NOT possible"); } } } else Logger.debug("No foreign bPKs required for this service provider"); } private void generateAdditonalbPK(MOAAuthenticationData authData, List additionalbPKSectorsRequested) throws EAAFBuilderException { if (additionalbPKSectorsRequested != null && !additionalbPKSectorsRequested.isEmpty()) { Logger.debug("Sectors for foreign bPKs are configurated. Starting foreign bPK generation ... "); for (String sector : additionalbPKSectorsRequested) { Logger.trace("Process sector: " + sector + " ... "); Pair bpk = new BPKBuilder().generateAreaSpecificPersonIdentifier( authData.getIdentificationValue(), authData.getIdentificationType(), sector); Logger.trace("Calculate additional bPK for sector: " + bpk.getSecond() + " with value: " + bpk.getFirst() ); authData.addAdditionalbPKPair(bpk); } } } }