diff options
Diffstat (limited to 'id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java')
-rw-r--r-- | id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java | 367 |
1 files changed, 234 insertions, 133 deletions
diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java index eb869756e..0ec0d95a2 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java @@ -26,21 +26,25 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.List; import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.namespace.QName; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import org.apache.commons.lang3.StringEscapeUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; import org.w3c.dom.Element; import org.xml.sax.SAXException; -import eu.stork.peps.auth.commons.IPersonalAttributeList; -import eu.stork.peps.auth.commons.PersonalAttribute; - +import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate; +import at.gv.e_government.reference.namespace.mandates._20040701_.Mandator; import at.gv.egovernment.moa.id.auth.AuthenticationServer; import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataAssertionBuilder; import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; @@ -49,7 +53,6 @@ import at.gv.egovernment.moa.id.auth.builder.SAMLArtifactBuilder; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttributeImpl; -import at.gv.egovernment.moa.id.auth.data.IdentityLink; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.exception.BuildException; import at.gv.egovernment.moa.id.auth.exception.ParseException; @@ -57,14 +60,16 @@ import at.gv.egovernment.moa.id.auth.exception.ServiceException; import at.gv.egovernment.moa.id.auth.exception.ValidateException; import at.gv.egovernment.moa.id.auth.parser.SAMLArtifactParser; import at.gv.egovernment.moa.id.auth.validator.parep.ParepUtils; +import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; +import at.gv.egovernment.moa.id.commons.api.IRequest; +import at.gv.egovernment.moa.id.commons.api.data.SAML1ConfigurationParameters; +import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; -import at.gv.egovernment.moa.id.config.ConfigurationException; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; -import at.gv.egovernment.moa.id.config.auth.data.SAML1ConfigurationParameters; import at.gv.egovernment.moa.id.data.AuthenticationData; -import at.gv.egovernment.moa.id.moduls.IRequest; -import at.gv.egovernment.moa.id.storage.AssertionStorage; -//import at.gv.egovernment.moa.id.util.IdentityLinkReSigner; +import at.gv.egovernment.moa.id.data.IAuthData; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; +import at.gv.egovernment.moa.id.storage.ITransactionStorage; import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.Base64Utils; @@ -77,20 +82,14 @@ import at.gv.util.xsd.persondata.IdentificationType.Value; import at.gv.util.xsd.persondata.PersonNameType; import at.gv.util.xsd.persondata.PersonNameType.FamilyName; import at.gv.util.xsd.persondata.PhysicalPersonType; +import eu.eidas.auth.commons.IPersonalAttributeList; +import eu.eidas.auth.commons.PersonalAttribute; +//import at.gv.egovernment.moa.id.util.IdentityLinkReSigner; +@Service("SAML1AuthenticationServer") public class SAML1AuthenticationServer extends AuthenticationServer { - - private static SAML1AuthenticationServer instance; - - public static SAML1AuthenticationServer getInstace() { - if (instance == null) - instance = new SAML1AuthenticationServer(); - return instance; - } - - private static AssertionStorage authenticationDataStore = AssertionStorage.getInstance(); - + @Autowired private ITransactionStorage authenticationDataStore; /** * time out in milliseconds used by {@link cleanup} for authentication data @@ -108,20 +107,23 @@ public class SAML1AuthenticationServer extends AuthenticationServer { samlArtifact, ex.toString() }); } Throwable error = null; - synchronized (authenticationDataStore) { - try { - error = authenticationDataStore - .get(samlArtifact, Throwable.class); + try { + error = authenticationDataStore + .get(samlArtifact, Throwable.class); - authenticationDataStore.remove(samlArtifact); - - } catch (MOADatabaseException e) { + if (error == null) { Logger.error("Assertion not found for SAML Artifact: " + samlArtifact); throw new AuthenticationException("1206", new Object[] { samlArtifact }); + } - + + authenticationDataStore.remove(samlArtifact); + + } catch (MOADatabaseException e) { + Logger.error("Assertion not found for SAML Artifact: " + samlArtifact); + throw new AuthenticationException("1206", new Object[] { samlArtifact }); } - + return error; } @@ -130,7 +132,7 @@ public class SAML1AuthenticationServer extends AuthenticationServer { * @param iPersonalAttributeList STORK attribute list * @return */ - public static List<ExtendedSAMLAttribute> addAdditionalSTORKAttributes(IPersonalAttributeList iPersonalAttributeList) { + public List<ExtendedSAMLAttribute> addAdditionalSTORKAttributes(IPersonalAttributeList iPersonalAttributeList) { List<ExtendedSAMLAttribute> moaExtendedSAMLAttributeList = new Vector<ExtendedSAMLAttribute>(); if(null == iPersonalAttributeList) @@ -178,22 +180,24 @@ public class SAML1AuthenticationServer extends AuthenticationServer { throw new AuthenticationException("1205", new Object[] { samlArtifact, ex.toString() }); } - String authData = null; - synchronized (authenticationDataStore) { - // System.out.println("assertionHandle: " + assertionHandle); - - try { - authData = authenticationDataStore - .get(samlArtifact, String.class, authDataTimeOut); + String authData = null; + try { + authData = authenticationDataStore + .get(samlArtifact, String.class, authDataTimeOut); - } catch (MOADatabaseException e) { + if (authData == null) { Logger.error("Assertion not found for SAML Artifact: " + samlArtifact); throw new AuthenticationException("1206", new Object[] { samlArtifact }); - } - } + + } - authenticationDataStore.remove(samlArtifact); + } catch (MOADatabaseException e) { + Logger.error("Assertion not found for SAML Artifact: " + samlArtifact); + throw new AuthenticationException("1206", new Object[] { samlArtifact }); + } + + authenticationDataStore.remove(samlArtifact); Logger.debug("Assertion delivered for SAML Artifact: " + samlArtifact); return authData; @@ -211,7 +215,7 @@ public class SAML1AuthenticationServer extends AuthenticationServer { return samlArtifact; } - public String BuildSAMLArtifact(OAAuthParameter oaParam, + public String BuildSAMLArtifact(IOAAuthParameters oaParam, SAML1AuthenticationData authData, String sourceID) throws ConfigurationException, BuildException, AuthenticationException { @@ -265,15 +269,20 @@ public class SAML1AuthenticationServer extends AuthenticationServer { person.getIdentification().add(id ); Value value = new Value(); id.setValue(value ); - - id.setType(authData.getIdentificationType()); - //add baseID if it is requested and available - if ( MiscUtil.isNotEmpty(authData.getIdentificationValue()) && - saml1parameter.isProvideIdentityLink() ) + + if ( MiscUtil.isNotEmpty(authData.getIdentificationValue()) && + saml1parameter.isProvideIdentityLink() && !authData.isBusinessService()) { + //add baseID if it is requested and available and SP is publicService value.setValue(authData.getIdentificationValue()); - else - value.setValue(""); - + id.setType(authData.getIdentificationType()); + + } else { + //otherwise add bPK + value.setValue(authData.getBPK()); + id.setType(authData.getBPKType()); + + } + familyName.setValue(authData.getFamilyName()); familyName.setPrimary("undefined"); name.getGivenName().add(authData.getGivenName()); @@ -313,14 +322,15 @@ public class SAML1AuthenticationServer extends AuthenticationServer { } - String samlAssertion; + String samlAssertion; + + //add mandate info's if (authData.isUseMandate()) { List<ExtendedSAMLAttribute> oaAttributes = authData.getExtendedSAMLAttributesOA(); - //only provide full mandate if it is included. - //In case of federation only a short mandate could be include + //only provide full mandate if it is included. if (saml1parameter.isProvideFullMandatorData() - && authData.getMISMandate().isFullMandateIncluded()) { + && authData.getMISMandate() != null) { try { @@ -436,7 +446,7 @@ public class SAML1AuthenticationServer extends AuthenticationServer { } - private String generateMandateDate(OAAuthParameter oaParam, AuthenticationData authData + private String generateMandateDate(IOAAuthParameters oaParam, AuthenticationData authData ) throws AuthenticationException, BuildException, ParseException, ConfigurationException, ServiceException, ValidateException { @@ -445,33 +455,36 @@ public class SAML1AuthenticationServer extends AuthenticationServer { throw new AuthenticationException("auth.10", new Object[] { REQ_VERIFY_AUTH_BLOCK, PARAM_SESSIONID }); - IdentityLink tempIdentityLink = null; - + Element prPerson = null; + String identificationType = ""; + String identificationValue = ""; + Element mandate = authData.getMandate(); + if (mandate == null) { + //no full-mandate include + Logger.info("AuthData contains no full-mandate. Starting 'mandateDate' generation from PVP attributes ..."); + mandate = generateMandateDateFromPVPMandateAttributes(authData); + + } - if (authData.isUseMandate()) { - tempIdentityLink = new IdentityLink(); + if (mandate != null) { Element mandator = ParepUtils.extractMandator(mandate); String dateOfBirth = ""; - Element prPerson = null; String familyName = ""; String givenName = ""; - String identificationType = ""; - String identificationValue = ""; if (mandator != null) { boolean physical = ParepUtils.isPhysicalPerson(mandator); if (physical) { - familyName = ParepUtils.extractText(mandator, - "descendant-or-self::pr:Name/pr:FamilyName/text()"); - givenName = ParepUtils.extractText(mandator, - "descendant-or-self::pr:Name/pr:GivenName/text()"); - dateOfBirth = ParepUtils - .extractMandatorDateOfBirth(mandator); + familyName = ParepUtils.extractText(mandator, "descendant-or-self::pr:Name/pr:FamilyName/text()"); + givenName = ParepUtils.extractText(mandator, "descendant-or-self::pr:Name/pr:GivenName/text()"); + dateOfBirth = ParepUtils.extractMandatorDateOfBirth(mandator); + } else { familyName = ParepUtils.extractMandatorFullName(mandator); + } - identificationType = ParepUtils.getIdentification(mandator, - "Type"); + + identificationType = ParepUtils.getIdentification(mandator, "Type"); identificationValue = ParepUtils.extractMandatorWbpk(mandator); prPerson = ParepUtils.extractPrPersonOfMandate(mandate); @@ -498,33 +511,19 @@ public class SAML1AuthenticationServer extends AuthenticationServer { ParepUtils .HideStammZahlen(prPerson, true, null, null, true); } - - tempIdentityLink.setDateOfBirth(dateOfBirth); - tempIdentityLink.setFamilyName(familyName); - tempIdentityLink.setGivenName(givenName); - tempIdentityLink.setIdentificationType(identificationType); - tempIdentityLink.setIdentificationValue(identificationValue); - tempIdentityLink.setPrPerson(prPerson); - try { - tempIdentityLink.setSamlAssertion(authData.getIdentityLink() - .getSamlAssertion()); - } catch (Exception e) { - throw new ValidateException("validator.64", null); - } - } - + } - - Element mandatePerson = tempIdentityLink.getPrPerson(); - - String mandateData = null; - try { + + if (prPerson == null) { + Logger.warn("Mandates are enabled, but no mandate-information is found in authData."); + throw new AuthenticationException("auth.16", new Object[] { "Mandates are enabled, but no mandate information is included" }); + } + + try { boolean provideStammzahl = oaParam.getSAML1Parameter().isProvideStammzahl(); - - String oatargetType; - + String oatargetType; if(oaParam.getBusinessService()) { if (oaParam.getIdentityLinkDomainIdentifier().startsWith(AuthenticationSession.REGISTERANDORDNR_PREFIX_)) oatargetType = oaParam.getIdentityLinkDomainIdentifier(); @@ -533,64 +532,166 @@ public class SAML1AuthenticationServer extends AuthenticationServer { } else { oatargetType = AuthenticationSession.TARGET_PREFIX_ + oaParam.getTarget(); + } - Element prIdentification = (Element) mandatePerson - .getElementsByTagNameNS(Constants.PD_NS_URI, - "Identification").item(0); + Element prIdentification = (Element) prPerson. + getElementsByTagNameNS(Constants.PD_NS_URI,"Identification").item(0); - if (!oatargetType.equals(tempIdentityLink.getIdentificationType())) { - - String isPrPerson = mandatePerson.getAttribute("xsi:type"); + if (!oatargetType.equals(identificationType)) { + String isPrPerson = prPerson.getAttribute("xsi:type"); if (!StringUtils.isEmpty(isPrPerson)) { if (isPrPerson.equalsIgnoreCase("pr:PhysicalPerson")) { - String baseid = getBaseId(mandatePerson); - Element identificationBpK = createIdentificationBPK(mandatePerson, - baseid, oaParam.getTarget()); - - if (!provideStammzahl) { - prIdentification.getFirstChild().setTextContent(""); + + String baseid = getBaseId(prPerson); + Element identificationBpK; + if (MiscUtil.isNotEmpty(baseid)) { + identificationBpK = createIdentificationBPK(prPerson, baseid, oaParam.getTarget()); + + if (!provideStammzahl) { + prIdentification.getFirstChild().setTextContent(""); + } + + prPerson.insertBefore(identificationBpK, + prIdentification); + + } else { + Logger.info("No baseID included. --> Build 'MandateDate' without baseID"); + } + + - mandatePerson.insertBefore(identificationBpK, - prIdentification); + } } } else { - -// Element identificationBpK = mandatePerson.getOwnerDocument() -// .createElementNS(Constants.PD_NS_URI, "Identification"); -// Element valueBpK = mandatePerson.getOwnerDocument().createElementNS( -// Constants.PD_NS_URI, "Value"); -// -// valueBpK.appendChild(mandatePerson.getOwnerDocument().createTextNode( -// tempIdentityLink.getIdentificationValue())); -// Element typeBpK = mandatePerson.getOwnerDocument().createElementNS( -// Constants.PD_NS_URI, "Type"); -// typeBpK.appendChild(mandatePerson.getOwnerDocument().createTextNode( -// "urn:publicid:gv.at:cdid+bpk")); -// identificationBpK.appendChild(valueBpK); -// identificationBpK.appendChild(typeBpK); -// -// mandatePerson.insertBefore(identificationBpK, prIdentification); + ; } - - mandateData = DOMUtils.serializeNode(mandatePerson); + return DOMUtils.serializeNode(prPerson); } catch (TransformerException e1) { - throw new AuthenticationException("auth.16", - new Object[] { GET_MIS_SESSIONID }); + throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID }); } catch (IOException e1) { - throw new AuthenticationException("auth.16", - new Object[] { GET_MIS_SESSIONID }); + throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID }); } - return mandateData; } + private Element generateMandateDateFromPVPMandateAttributes(IAuthData authdata) throws BuildException { + String legalSourcePin = authdata.getGenericData(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_NAME, String.class); + String legalSourceType = authdata.getGenericData(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME, String.class); + String legalCommonName = authdata.getGenericData(PVPConstants.MANDATE_LEG_PER_FULL_NAME_NAME, String.class); + + String natSourcePin = authdata.getGenericData(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_NAME, String.class); + String natSourcePinType = authdata.getGenericData(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_TYPE_NAME, String.class); + String natbPK = authdata.getGenericData(PVPConstants.MANDATE_NAT_PER_BPK_NAME, String.class); + + String natGivenName = authdata.getGenericData(PVPConstants.MANDATE_NAT_PER_GIVEN_NAME_NAME, String.class); + String natFamilyName = authdata.getGenericData(PVPConstants.MANDATE_NAT_PER_FAMILY_NAME_NAME, String.class); + String natDateOfBirth = authdata.getGenericData(PVPConstants.MANDATE_NAT_PER_BIRTHDATE_NAME, String.class); + + Mandate mandateObject = new Mandate(); + Mandator mandator = new Mandator(); + mandateObject.setMandator(mandator); + + if (MiscUtil.isNotEmpty(legalCommonName) && MiscUtil.isNotEmpty(legalSourceType) + && MiscUtil.isNotEmpty(legalSourcePin)) { + Logger.debug("Build 'mandateDate' element for legal person ..."); + at.gv.e_government.reference.namespace.persondata._20020228_.CorporateBodyType legalperson = + new at.gv.e_government.reference.namespace.persondata._20020228_.CorporateBodyType(); + at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType legalID = + new at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType(); + at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value idvalue = + new at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value(); + + legalID.setValue(idvalue ); + legalperson.getIdentification().add(legalID ); + mandator.setCorporateBody(legalperson); + legalperson.setFullName(legalCommonName); + legalID.setType(legalSourceType); + idvalue.setValue(legalSourcePin); + + } else if (MiscUtil.isNotEmpty(natFamilyName) && MiscUtil.isNotEmpty(natGivenName) && MiscUtil.isNotEmpty(natDateOfBirth) + && (MiscUtil.isNotEmpty(natSourcePin) || MiscUtil.isNotEmpty(natbPK))){ + Logger.debug("Build 'mandateDate' element for natural person ..."); + at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType physPerson = + new at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType(); + at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType persName = + new at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType(); + at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType.FamilyName familyName = + new at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType.FamilyName(); + at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType persID = + new at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType(); + at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value idValue = + new at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value(); + + physPerson.setName(persName ); + persName.getFamilyName().add(familyName ); + physPerson.getIdentification().add(persID ); + persID.setValue(idValue ); + mandator.setPhysicalPerson(physPerson); + + String[] pvp2GivenName = natGivenName.split(" "); + for(int i=0; i<pvp2GivenName.length; i++) + persName.getGivenName().add(pvp2GivenName[i]); + + familyName.setValue(natFamilyName); + physPerson.setDateOfBirth(natDateOfBirth); + + if (MiscUtil.isNotEmpty(natSourcePin)) { + persID.setType(Constants.URN_PREFIX_BASEID); + idValue.setValue(natSourcePin); + + } else { + String[] pvp2bPK = natbPK.split(":"); + if (pvp2bPK.length == 2) { + idValue.setValue(pvp2bPK[1]); + Pattern pattern = Pattern.compile(MOAIDAuthConstants.REGEX_PATTERN_TARGET); + Matcher matcher = pattern.matcher(pvp2bPK[0]); + if (matcher.matches()) + persID.setType(Constants.URN_PREFIX_CDID + "+" + pvp2bPK[0]); + + //TODO: maybe change to this, because original SAML1 response has + // target Constants.URN_PREFIX_BPK + //persID.setType(Constants.URN_PREFIX_BPK); + + + else + persID.setType(Constants.URN_PREFIX_WBPK + "+" + pvp2bPK[0]); + + } else { + Logger.warn("Receive mandator bPK from federation with an unsupported format. " + natbPK); + throw new BuildException("auth.16", new Object[]{"Receive mandator bPK from federation with an unsupported format."}); + + } + } + + } else { + Logger.error("mandateDate' elemente could not generated. AuthData contains not all PVP-attributes which are necessary."); + throw new BuildException("auth.16", new Object[]{"'mandateDate' elemente could not generated. AuthData contains not all PVP-attributes which are necessary."}); + + } + + try { + JAXBContext jc = JAXBContext.newInstance("at.gv.e_government.reference.namespace.mandates._20040701_"); + Marshaller m = jc.createMarshaller(); + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + m.marshal(mandateObject, stream); + stream.close(); + + return DOMUtils.parseDocument(new String(stream.toByteArray(), "UTF-8"), false, null, null).getDocumentElement(); + + } catch (JAXBException | IOException | SAXException | ParserConfigurationException e) { + Logger.error("Failed to parse short mandate", e); + throw new BuildException("auth.16", new Object[]{"Failed to parse 'mandateDate element'"}, e); + + } + + } @@ -617,11 +718,11 @@ public class SAML1AuthenticationServer extends AuthenticationServer { new Object[] { samlArtifact }); parser.parseAssertionHandle(); - synchronized (authenticationDataStore) { + //synchronized (authenticationDataStore) { Logger.debug("Assertion stored for SAML Artifact: " + samlArtifact); authenticationDataStore.put(samlArtifact, samlAssertion); - } + //} } catch (AuthenticationException ex) { throw ex; |