From 1626ac9867cd5406b83e73651080e33c11fb98d1 Mon Sep 17 00:00:00 2001 From: kstranacher_eGovL Date: Thu, 12 Jul 2012 11:27:13 +0000 Subject: Integration of STORK git-svn-id: https://joinup.ec.europa.eu/svn/moa-idspss/trunk@1285 d688527b-c9ab-4aba-bd8d-4036d912da1d --- .../messages/builder/STORKMessagesBuilder.java | 1367 ++++++++++++++++++++ 1 file changed, 1367 insertions(+) create mode 100644 id/server/stork-saml-engine/src/main/java/eu/stork/vidp/messages/builder/STORKMessagesBuilder.java (limited to 'id/server/stork-saml-engine/src/main/java/eu/stork/vidp/messages/builder/STORKMessagesBuilder.java') diff --git a/id/server/stork-saml-engine/src/main/java/eu/stork/vidp/messages/builder/STORKMessagesBuilder.java b/id/server/stork-saml-engine/src/main/java/eu/stork/vidp/messages/builder/STORKMessagesBuilder.java new file mode 100644 index 000000000..2f9a19620 --- /dev/null +++ b/id/server/stork-saml-engine/src/main/java/eu/stork/vidp/messages/builder/STORKMessagesBuilder.java @@ -0,0 +1,1367 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * The Austrian STORK Modules have been developed by the E-Government + * Innovation Center EGIZ, a joint initiative of the Federal Chancellery + * Austria 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 eu.stork.vidp.messages.builder; + +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.DateTime; +import org.opensaml.Configuration; +import org.opensaml.common.IdentifierGenerator; +import org.opensaml.common.SAMLObject; +import org.opensaml.common.SAMLObjectBuilder; +import org.opensaml.common.SAMLVersion; +import org.opensaml.common.impl.SecureRandomIdentifierGenerator; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.core.Assertion; +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.core.AttributeStatement; +import org.opensaml.saml2.core.AttributeValue; +import org.opensaml.saml2.core.Audience; +import org.opensaml.saml2.core.AudienceRestriction; +import org.opensaml.saml2.core.AuthnContext; +import org.opensaml.saml2.core.AuthnStatement; +import org.opensaml.saml2.core.Conditions; +import org.opensaml.saml2.core.Issuer; +import org.opensaml.saml2.core.NameID; +import org.opensaml.saml2.core.OneTimeUse; +import org.opensaml.saml2.core.Status; +import org.opensaml.saml2.core.StatusCode; +import org.opensaml.saml2.core.StatusDetail; +import org.opensaml.saml2.core.StatusMessage; +import org.opensaml.saml2.core.Subject; +import org.opensaml.saml2.core.SubjectConfirmation; +import org.opensaml.saml2.core.SubjectConfirmationData; +import org.opensaml.saml2.core.SubjectLocality; +import org.opensaml.saml2.metadata.RequestedAttribute; +import org.opensaml.ws.soap.common.SOAPObject; +import org.opensaml.ws.soap.common.SOAPObjectBuilder; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.XMLObjectBuilder; +import org.opensaml.xml.schema.XSAny; +import org.opensaml.xml.schema.XSString; +import org.opensaml.xml.schema.impl.XSAnyBuilder; +import org.opensaml.xml.schema.impl.XSStringBuilder; +import org.opensaml.xml.signature.KeyInfo; +import org.opensaml.xml.signature.X509Data; +import org.opensaml.xml.util.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.stork.mw.messages.saml.STORKAuthnRequest; +import eu.stork.mw.messages.saml.STORKResponse; +import eu.stork.vidp.messages.common.STORKConstants; +import eu.stork.vidp.messages.saml.STORKAttribute; +import eu.stork.vidp.messages.saml.STORKAttributeValue; +import eu.stork.vidp.messages.saml.STORKExtensions; +import eu.stork.vidp.messages.saml.STORKRequestedAttribute; +import eu.stork.vidp.messages.stork.AuthenticationAttributes; +import eu.stork.vidp.messages.stork.CitizenCountryCode; +import eu.stork.vidp.messages.stork.EIDCrossBorderShare; +import eu.stork.vidp.messages.stork.EIDCrossSectorShare; +import eu.stork.vidp.messages.stork.EIDSectorShare; +import eu.stork.vidp.messages.stork.QualityAuthenticationAssuranceLevel; +import eu.stork.vidp.messages.stork.RequestedAttributes; +import eu.stork.vidp.messages.stork.SPAuthRequest; +import eu.stork.vidp.messages.stork.SPCertEnc; +import eu.stork.vidp.messages.stork.SPCertSig; +import eu.stork.vidp.messages.stork.SPCertType; +import eu.stork.vidp.messages.stork.SPID; +import eu.stork.vidp.messages.stork.SPInformation; +import eu.stork.vidp.messages.stork.SpApplication; +import eu.stork.vidp.messages.stork.SpCountry; +import eu.stork.vidp.messages.stork.SpInstitution; +import eu.stork.vidp.messages.stork.SpSector; +import eu.stork.vidp.messages.stork.VIDPAuthenticationAttributes; + +/** + * Class providing several methods for SAML Object generation + * @author bzwattendorfer + * + */ +public class STORKMessagesBuilder { + + final static Logger log = LoggerFactory.getLogger(STORKMessagesBuilder.class); + + /** + * Builds an arbitrary OpenSAML XML object + * @param OpenSAML XMLObject + * @param objectQName QName of the XML element + * @return Builded OpenSAML XMLObject + */ + @SuppressWarnings("unchecked") + public static T buildXMLObject(QName objectQName) { + + try { + XMLObjectBuilder builder = (XMLObjectBuilder) Configuration.getBuilderFactory().getBuilder(objectQName); + return builder.buildObject(objectQName.getNamespaceURI(), objectQName.getLocalPart(), objectQName.getPrefix()); + } catch (Exception e) { + log.error("Cannot build XML Object {}: {}", objectQName.getLocalPart(), e); + throw new RuntimeException(e); + } + + } + + /** + * Builds a SOAP object + * @param SOAP Object or any extensions + * @param objectQName QName of the XML element + * @return SOAP Object or any extensions + */ + @SuppressWarnings("unchecked") + public static T buildSOAPObject(QName objectQName) { + + try { + SOAPObjectBuilder builder = (SOAPObjectBuilder) Configuration.getBuilderFactory().getBuilder(objectQName); + return builder.buildObject(); + } catch (Exception e) { + log.error("Cannot build SOAP Object {}: {}", objectQName.getLocalPart(), e); + throw new RuntimeException(e); + } + + } + + /** + * Builds an arbitrary OpenSAML SAML object + * @param OpenSAML SAML Object + * @param objectQName QName of the SAML element + * @return Builded OpenSAML SAML Object + */ + @SuppressWarnings("unchecked") + public static T buildSAMLObject(QName objectQName) { + + try { + SAMLObjectBuilder builder = (SAMLObjectBuilder) Configuration.getBuilderFactory().getBuilder(objectQName); + return builder.buildObject(); + } catch (Exception e) { + log.error("Cannot build SAML Object {}: {}", objectQName.getLocalPart(), e); + throw new RuntimeException(e); + } + + } + + + + /** + * Builds SAML Issuer object + * @param issuerValue Value for the issuer element + * @return Issuer object + */ + public static Issuer buildIssuer(String issuerValue) { + if (StringUtils.isEmpty(issuerValue)) + return null; + + Issuer issuer = buildXMLObject(Issuer.DEFAULT_ELEMENT_NAME); + issuer.setValue(issuerValue); + issuer.setFormat(Issuer.ENTITY); + + return issuer; + } + + /** + * Builds a QualityAuthenticationAssuranceLevel object + * @param qaaValue QAALevel (1 to 4) + * @return QualityAuthenticationAssuranceLevel object + */ + public static QualityAuthenticationAssuranceLevel buildQualityAuthenticationAssuranceLevel(int qaaValue) { + if (qaaValue < 1 || qaaValue > 4) { + log.error("QAA Level must be between 1 and 4."); + return null; + } + + QualityAuthenticationAssuranceLevel qaaLevel = buildXMLObject(QualityAuthenticationAssuranceLevel.DEFAULT_ELEMENT_NAME); + qaaLevel.setValue(qaaValue); + return qaaLevel; + } + + /** + * Builds a STORK RequestedAttribute object + * @param name Name of the RequesteAttribute + * @param isRequired true or false if RequestedAttribute is required + * @param value Value of RequestedAttribute + * @return STORK RequestedAttribute object + */ + public static RequestedAttribute buildRequestedAttribute(String name, boolean isRequired, String value) { + + RequestedAttribute reqAttribute = buildXMLObject(STORKRequestedAttribute.DEFAULT_ELEMENT_NAME); + reqAttribute.setName(name); + reqAttribute.setNameFormat(STORKRequestedAttribute.URI_REFERENCE); + reqAttribute.setIsRequired(isRequired); + + if (!StringUtils.isEmpty(value)) { + XSString stringValue = buildXSString(STORKAttributeValue.DEFAULT_ELEMENT_NAME); + stringValue.setValue(value); + reqAttribute.getAttributeValues().add(stringValue); + } + + return reqAttribute; + } + + /** + * Builds XML String type object with given QName + * @param qname QName for object to build + * @return XML object as String type + */ + public static XSString buildXSString(QName qname) { + XSStringBuilder stringBuilder = (XSStringBuilder) Configuration.getBuilderFactory().getBuilder(XSString.TYPE_NAME); + return stringBuilder.buildObject(qname, XSString.TYPE_NAME); + } + + /** + * Builds XML Any type object with given QName + * @param qname QName for object to build + * @return XML object as Any type + */ + public static XSAny buildXSAny(QName qname) { + XSAnyBuilder anyBuilder = (XSAnyBuilder) Configuration.getBuilderFactory().getBuilder(XSAny.TYPE_NAME); + return anyBuilder.buildObject(qname, XSAny.TYPE_NAME); + } + + /** + * Builds a List of RequestedAttribute + * @param requestedAttributeArguments RequestedAttributes + * @return List of RequestedAttribute + */ + public static RequestedAttributes buildRequestedAttributes(RequestedAttribute... requestedAttributeArguments) { + + if (requestedAttributeArguments == null) + return null; + + RequestedAttributes reqAttributes = buildXMLObject(RequestedAttributes.DEFAULT_ELEMENT_NAME); + + for (RequestedAttribute reqAttr : requestedAttributeArguments) { + reqAttributes.getRequestedAttributes().add(reqAttr); + } + + return reqAttributes; + } + + /** + * Builds RequestedAttributes object out of list of RequestedAttribute + * @param requestedAttributeList List of RequestedAttribute + * @return RequestedAttributes object + */ + public static RequestedAttributes buildRequestedAttributes(List requestedAttributeList) { + if (requestedAttributeList == null) + return null; + + RequestedAttributes reqAttributes = buildXMLObject(RequestedAttributes.DEFAULT_ELEMENT_NAME); + reqAttributes.getRequestedAttributes().addAll(requestedAttributeList); + + return reqAttributes; + } + + /** + * Builds a STORK CitizenCountryCode object + * @param ccc ISO country code + * @return CitizenCountryCode object + */ + public static CitizenCountryCode buildCitizenCountryCode(String ccc) { + if (StringUtils.isEmpty(ccc)) { + log.error("CitizenCountryCode must have a value."); + return null; + } + + CitizenCountryCode citizenCountryCode = buildXMLObject(CitizenCountryCode.DEFAULT_ELEMENT_NAME); + citizenCountryCode.setValue(ccc); + + return citizenCountryCode; + } + + /** + * Builds a SPID object + * @param spIDString String to be used as SPID + * @return SPID object + */ + public static SPID buildSPID(String spIDString) { + if (StringUtils.isEmpty(spIDString)) { + log.error("SPID must have a value."); + return null; + } + + SPID spID = buildXMLObject(SPID.DEFAULT_ELEMENT_NAME); + spID.setValue(spIDString); + + return spID; + } + + /** + * Builds SPCertType + * @param cert X509Certificate + * @return SPCertType + */ + private static SPCertType buildSPCertType(X509Certificate cert) { + SPCertType spCertType = buildXMLObject(SPCertType.TYPE_NAME); + KeyInfo keyInfo = buildXMLObject(KeyInfo.DEFAULT_ELEMENT_NAME); + X509Data x509DataElem = buildXMLObject(X509Data.DEFAULT_ELEMENT_NAME); + org.opensaml.xml.signature.X509Certificate x509CertElem = buildXMLObject(org.opensaml.xml.signature.X509Certificate.DEFAULT_ELEMENT_NAME); + + try { + x509CertElem.setValue(Base64.encodeBytes(cert.getEncoded())); + } catch (CertificateEncodingException e) { + log.error("Cannot encode certificate.", e); + throw new RuntimeException(e); + } + + x509DataElem.getX509Certificates().add(x509CertElem); + keyInfo.getX509Datas().add(x509DataElem); + spCertType.setKeyInfo(keyInfo); + return spCertType; + } + + /** + * Builds SPCertSig object + * @param cert X509Certificate + * @return SPCertSig + */ + public static SPCertSig buildSPCertSig(X509Certificate cert) { + return (SPCertSig) buildSPCertType(cert); + } + + /** + * Builds SPCertEnc object + * @param cert X509Certificate + * @return SPCertEnc + */ + public static SPCertEnc buildSPCertEnc(X509Certificate cert) { + return (SPCertEnc) buildSPCertType(cert); + } + + /** + * Builds SPAuthRequest object + * @param xmlObject Abritrary XML object + * @return SPAuthRequest + */ + public static SPAuthRequest buildSPAuthRequest(XMLObject xmlObject) { + SPAuthRequest authRequest = buildXMLObject(SPAuthRequest.DEFAULT_ELEMENT_NAME); + authRequest.getUnknownXMLObjects().add(xmlObject); + return authRequest; + } + + /** + * Builds SPInformation object + * @param spIDString SPID + * @param sigCert SP signature certificate + * @param encCert SP encryption certificate + * @param spAuthRequest Original SP AuthnRequest + * @return SPInformations + */ + public static SPInformation buildSPInformation(String spIDString, X509Certificate sigCert, X509Certificate encCert, XMLObject spAuthRequest) { + + SPInformation spInformation = buildXMLObject(SPInformation.DEFAULT_ELEMENT_NAME); + + SPID spID = buildSPID(spIDString); + spInformation.setSPID(spID); + + if (sigCert != null) { + SPCertSig spCertSig = buildSPCertSig(sigCert); + spInformation.setSPCertSig(spCertSig); + } + + if (encCert != null) { + SPCertEnc spCertEnc = buildSPCertEnc(encCert); + spInformation.setSPCertEnc(spCertEnc); + } + + if (spAuthRequest != null) { + SPAuthRequest spAuthRequestElem = buildSPAuthRequest(spAuthRequest); + spInformation.setSPAuthRequest(spAuthRequestElem); + } + + return spInformation; + + } + + /** + * Builds VIDPAuthenticationAttributes objext + * @param ccc ISO citizen country code + * @param spIDString SPID + * @param sigCert SP signature certificate + * @param encCert SP encryption certificate + * @param spAuthRequest Original SP AuthnRequest + * @return VIDPAuthenticationAttributes + */ + public static VIDPAuthenticationAttributes buildVIDPAuthenticationAttributes(String ccc, String spIDString, X509Certificate sigCert, X509Certificate encCert, XMLObject spAuthRequest) { + VIDPAuthenticationAttributes vidpAuthenticationAttributes = buildXMLObject(VIDPAuthenticationAttributes.DEFAULT_ELEMENT_NAME); + + CitizenCountryCode citizenCountryCode = buildCitizenCountryCode(ccc); + SPInformation spInformation = buildSPInformation(spIDString, sigCert, encCert, spAuthRequest); + + vidpAuthenticationAttributes.setCitizenCountryCode(citizenCountryCode); + vidpAuthenticationAttributes.setSPInformation(spInformation); + + return vidpAuthenticationAttributes; + } + + /** + * Builds AuthenticationAttributes object + * @param ccc ISO citizen country code + * @param spIDString SPID + * @param sigCert SP signature certificate + * @param encCert SP encryption certificate + * @param spAuthRequest Original SP AuthnRequest + * @return AuthenticationAttributes + */ + public static AuthenticationAttributes buildAuthenticationAttributes(String ccc, String spIDString, X509Certificate sigCert, X509Certificate encCert, XMLObject spAuthRequest) { + AuthenticationAttributes authenticationAttributes = buildXMLObject(AuthenticationAttributes.DEFAULT_ELEMENT_NAME); + + VIDPAuthenticationAttributes vidpAuthenticationAttributes = buildVIDPAuthenticationAttributes(ccc, spIDString, sigCert, encCert, spAuthRequest); + + authenticationAttributes.setVIDPAuthenticationAttributes(vidpAuthenticationAttributes); + return authenticationAttributes; + + } + + /** + * Builds SpSector object + * @param spSector Value SPSector value + * @return SpSector + */ + public static SpSector buildSpSector(String spSectorValue) { + + SpSector spSector = buildXMLObject(SpSector.DEFAULT_ELEMENT_NAME); + spSector.setValue(spSectorValue); + + return spSector; + } + + /** + * Builds SpInstitution object + * @param spInstitutionValue Value for SpInstitution + * @return SpInstitution + */ + public static SpInstitution buildSpInstitution(String spInstitutionValue) { + + SpInstitution spInstitution = buildXMLObject(SpInstitution.DEFAULT_ELEMENT_NAME); + spInstitution.setValue(spInstitutionValue); + + return spInstitution; + } + + + /** + * Builds SpApplication object + * @param spApplicationValue Value for SpApplication + * @return SpApplication + */ + public static SpApplication buildSpApplication(String spApplicationValue) { + + SpApplication spApplication = buildXMLObject(SpApplication.DEFAULT_ELEMENT_NAME); + spApplication.setValue(spApplicationValue); + + return spApplication; + } + + /** + * Builds SpCountry object + * @param spCountryValue ISO Code Value for SpCountry + * @return SpCountry + */ + public static SpCountry buildSpCountry(String spCountryValue) { + + SpCountry spCountry = buildXMLObject(SpCountry.DEFAULT_ELEMENT_NAME); + spCountry.setValue(spCountryValue); + + return spCountry; + } + + /** + * Generates secured randomized ID for SAML Messages + * @return secured randomized ID + */ + public static String generateID() { + try { + IdentifierGenerator idGenerator = new SecureRandomIdentifierGenerator(); + return idGenerator.generateIdentifier(); + } catch (NoSuchAlgorithmException e) { + log.error("Cannot generate id", e); + throw new RuntimeException(e); + + } + + } + + /** + * Builds STORKAuthnRequest object + * @param destination Endpoint for AuthnRequest + * @param acsURL Endpoint where STORK response wants to be received + * @param providerName Provider Name + * @param issuerValue Value for Issuer element + * @param qaaLevel STORK QAALevel + * @param requestedAttributes Attributes to be requested + * @param spSector SPSector + * @param spInstitution SPInstitution + * @param spApplication SPApplication + * @param spCountry SPCountry + * @return STORKAuthnRequest + */ + public static STORKAuthnRequest buildSTORKAuthnRequest( + String destination, + String acsURL, + String providerName, + String issuerValue, + QualityAuthenticationAssuranceLevel qaaLevel, + RequestedAttributes requestedAttributes, + String spSector, + String spInstitution, + String spApplication, + String spCountry) { + + //fixed values + String consent = STORKAuthnRequest.UNSPECIFIED_CONSENT; + boolean forceAuthn = true; + boolean isPassive = false; + String binding = SAMLConstants.SAML2_POST_BINDING_URI; + boolean eIDSectorShare = true; + boolean eIDCrossSectorShare = true; + boolean eIDCrossBorderShare = false; + + STORKAuthnRequest authnRequest = buildXMLObject(STORKAuthnRequest.DEFAULT_ELEMENT_NAME); + + authnRequest.setVersion(SAMLVersion.VERSION_20); + authnRequest.setID(generateID()); + authnRequest.setIssueInstant(new DateTime()); + + authnRequest.setConsent(consent); + authnRequest.setForceAuthn(forceAuthn); + authnRequest.setIsPassive(isPassive); + authnRequest.setProtocolBinding(binding); + + authnRequest.setDestination(destination); + authnRequest.setAssertionConsumerServiceURL(acsURL); + authnRequest.setProviderName(providerName); + authnRequest.setIssuer(buildIssuer(issuerValue)); + + STORKExtensions extensions = buildSTORKExtensions(); + + authnRequest.setQAALevel(qaaLevel.getValue()); + extensions.setQAALevel(qaaLevel); + + authnRequest.setRequestedAttributes(requestedAttributes.getRequestedAttributes()); + extensions.setRequestedAttributes(requestedAttributes); + + EIDSectorShare eidSectorShareObj = buildXMLObject(EIDSectorShare.DEFAULT_ELEMENT_NAME); + eidSectorShareObj.setValue(eIDSectorShare); + + EIDCrossSectorShare eidCrossSectorShareObj = buildXMLObject(EIDCrossSectorShare.DEFAULT_ELEMENT_NAME); + eidCrossSectorShareObj.setValue(eIDCrossSectorShare); + + EIDCrossBorderShare eidCrossBorderShareObj = buildXMLObject(EIDCrossBorderShare.DEFAULT_ELEMENT_NAME); + eidCrossBorderShareObj.setValue(eIDCrossBorderShare); + + SpSector spSectorObj = buildSpSector(spSector); + SpInstitution spInstitutionObj = buildSpInstitution(spInstitution); + SpApplication spApplicationObj = buildSpApplication(spApplication); + SpCountry spCountryObj = buildSpCountry(spCountry); + + + extensions.getUnknownXMLObjects().add(qaaLevel); + extensions.getUnknownXMLObjects().add(spSectorObj); + extensions.getUnknownXMLObjects().add(spInstitutionObj); + extensions.getUnknownXMLObjects().add(spApplicationObj); + extensions.getUnknownXMLObjects().add(spCountryObj); + extensions.getUnknownXMLObjects().add(eidSectorShareObj); + extensions.getUnknownXMLObjects().add(eidCrossSectorShareObj); + extensions.getUnknownXMLObjects().add(eidCrossBorderShareObj); + extensions.getUnknownXMLObjects().add(requestedAttributes); + + authnRequest.setExtensions(extensions); + + return authnRequest; + } + + /** + * Builds STORKAuthnRequest object + * @param destination Endpoint for AuthnRequest + * @param acsURL Endpoint where STORK response wants to be received + * @param providerName Provider Name + * @param issuerValue Value for Issuer element + * @param qaaLevel STORK QAALevel + * @param requestedAttributeList List of STORK attributes to be requested + * @param ccc ISO citizen country code + * @param spIDString SPID + * @param sigCert SP signature certificate + * @param encCert SP encryption certificate + * @param spAuthRequest Original SP AuthnRequest + * @param spSector SPSector + * @param spInstitution SPInstitution + * @param spApplication SPApplication + * @param spCountry SPCountry + * @return STORKAuthnRequest + */ + public static STORKAuthnRequest buildSTORKAuthnRequest( + String destination, + String acsURL, + String providerName, + String issuerValue, + int qaaLevel, + List requestedAttributeList, + String ccc, + String spID, + X509Certificate sigCert, + X509Certificate encCert, + XMLObject spAuthRequest, + String spSector, + String spInstitution, + String spApplication, + String spCountry) { + + //fixed values via config + String consent = STORKAuthnRequest.UNSPECIFIED_CONSENT; + boolean forceAuthn = true; + boolean isPassive = false; + String binding = SAMLConstants.SAML2_POST_BINDING_URI; + boolean eIDSectorShare = true; + boolean eIDCrossSectorShare = true; + boolean eIDCrossBorderShare = false; + + return buildSTORKAuthnRequest(consent, forceAuthn, isPassive, binding, eIDSectorShare, eIDCrossSectorShare, eIDCrossBorderShare, destination, acsURL, providerName, issuerValue, qaaLevel, requestedAttributeList, ccc, spID, sigCert, encCert, spAuthRequest, spSector, spInstitution, spApplication, spCountry); + + } + + /** + * Builds STORKAuthnRequest object + * @param consent Consent for the request + * @param forceAuthn forceAuthn + * @param isPassive isPassive + * @param binding Binding the request is sent over + * @param eIDSectorShare Should eIdentifier be shared? + * @param eIDCrossSectorShare Should eIdentifier be shared across sectors? + * @param eIDCrossBorderShare Should eIdentifier be shared across borders? + * @param destination Endpoint for AuthnRequest + * @param acsURL Endpoint where STORK response wants to be received + * @param providerName Provider Name + * @param issuerValue Value for Issuer element + * @param qaaLevel STORK QAALevel + * @param requestedAttributeList List of STORK attributes to be requested + * @param ccc ISO citizen country code + * @param spIDString SPID + * @param sigCert SP signature certificate + * @param encCert SP encryption certificate + * @param spAuthRequest Original SP AuthnRequest + * @param spSector SPSector + * @param spInstitution SPInstitution + * @param spApplication SPApplication + * @param spCountry SPCountry + * @return STORKAuthnRequest + */ + public static STORKAuthnRequest buildSTORKAuthnRequest( + String consent, + boolean forceAuthn, + boolean isPassive, + String binding, + boolean eIDSectorShare, + boolean eIDCrossSectorShare, + boolean eIDCrossBorderShare, + String destination, + String acsURL, + String providerName, + String issuerValue, + int qaaLevel, + List requestedAttributeList, + String ccc, + String spID, + X509Certificate sigCert, + X509Certificate encCert, + XMLObject spAuthRequest, + String spSector, + String spInstitution, + String spApplication, + String spCountry) { + + STORKAuthnRequest authnRequest = buildXMLObject(STORKAuthnRequest.DEFAULT_ELEMENT_NAME); + + authnRequest.setVersion(SAMLVersion.VERSION_20); + authnRequest.setID(generateID()); + authnRequest.setIssueInstant(new DateTime()); + + authnRequest.setDestination(destination); + authnRequest.setAssertionConsumerServiceURL(acsURL); + authnRequest.setProviderName(providerName); + authnRequest.setIssuer(buildIssuer(issuerValue)); + authnRequest.setQAALevel(qaaLevel); + authnRequest.setRequestedAttributes(requestedAttributeList); + authnRequest.setCitizenCountryCode(ccc); + authnRequest.setSPID(spID); + authnRequest.setSPCertSig(sigCert); + authnRequest.setSPCertEnc(encCert); + authnRequest.setOriginalSPAuthRequest(spAuthRequest); + + authnRequest.setConsent(consent); + authnRequest.setForceAuthn(forceAuthn); + authnRequest.setIsPassive(isPassive); + authnRequest.setProtocolBinding(binding); + + addSTORKExtensionsToAuthnRequest(authnRequest, qaaLevel, requestedAttributeList, ccc, spID, sigCert, encCert, spAuthRequest, eIDSectorShare, eIDCrossSectorShare, eIDCrossBorderShare, spSector, spInstitution, spApplication, spCountry); + + return authnRequest; + + } + + /** + * Adds STORK Extensions to STORKAuthnRequest + * @param authnRequest + * @param qaaLevel STORK QAALevel + * @param requestedAttributeList List of STORK attributes to be requested + * @param ccc ISO citizen country code + * @param spIDString SPID + * @param sigCert SP signature certificate + * @param encCert SP encryption certificate + * @param spAuthRequest Original SP AuthnRequest + * @param spSector SPSector + * @param spInstitution SPInstitution + * @param spApplication SPApplication + * @param spCountry SPCountry + */ + public static void addSTORKExtensionsToAuthnRequest( + STORKAuthnRequest authnRequest, + int qaaLevel, + List requestedAttributeList, + String ccc, + String spID, + X509Certificate sigCert, + X509Certificate encCert, + XMLObject spAuthRequest, + boolean eIDSectorShare, + boolean eIDCrossSectorShare, + boolean eIDCrossBorderShare, + String spSector, + String spInstitution, + String spApplication, + String spCountry) { + + STORKExtensions extensions = buildSTORKExtensions(); + authnRequest.setRequestedAttributes(requestedAttributeList); + + QualityAuthenticationAssuranceLevel qaaLevelObj = buildQualityAuthenticationAssuranceLevel(qaaLevel); + RequestedAttributes requestedAttributesObj = buildRequestedAttributes(requestedAttributeList); + AuthenticationAttributes authenticationAttributesObj = buildAuthenticationAttributes(ccc, spID, sigCert, encCert, spAuthRequest); + + EIDSectorShare eidSectorShareObj = buildXMLObject(EIDSectorShare.DEFAULT_ELEMENT_NAME); + eidSectorShareObj.setValue(eIDSectorShare); + + EIDCrossSectorShare eidCrossSectorShareObj = buildXMLObject(EIDCrossSectorShare.DEFAULT_ELEMENT_NAME); + eidCrossSectorShareObj.setValue(eIDCrossSectorShare); + + EIDCrossBorderShare eidCrossBorderShareObj = buildXMLObject(EIDCrossBorderShare.DEFAULT_ELEMENT_NAME); + eidCrossBorderShareObj.setValue(eIDCrossBorderShare); + + SpSector spSectorObj = buildSpSector(spSector); + SpApplication spApplicationObj = buildSpApplication(spApplication); + SpCountry spCountryObj = buildSpCountry(spCountry); + + extensions.setQAALevel(qaaLevelObj); + extensions.setRequestedAttributes(requestedAttributesObj); + extensions.setAuthenticationAttributes(authenticationAttributesObj); + + extensions.getUnknownXMLObjects().add(qaaLevelObj); + extensions.getUnknownXMLObjects().add(spSectorObj); + extensions.getUnknownXMLObjects().add(spApplicationObj); + extensions.getUnknownXMLObjects().add(spCountryObj); + extensions.getUnknownXMLObjects().add(eidSectorShareObj); + extensions.getUnknownXMLObjects().add(eidCrossSectorShareObj); + extensions.getUnknownXMLObjects().add(eidCrossBorderShareObj); + extensions.getUnknownXMLObjects().add(requestedAttributesObj); + extensions.getUnknownXMLObjects().add(authenticationAttributesObj); + + authnRequest.setExtensions(extensions); + + } + + + /** + * Builds STORKExtensions object + * @return STORKExtensions + */ + public static STORKExtensions buildSTORKExtensions() { + QName samlProtocolExtensions = new QName(SAMLConstants.SAML20P_NS, STORKExtensions.LOCAL_NAME, SAMLConstants.SAML20P_PREFIX); + return buildXMLObject(samlProtocolExtensions); + } + + /** + * Builds STORKResponse + * @param destination Endpoint where the STORKResponse should be sent to + * @param inResponseTo ID of the corresponding AuthnRequest + * @param issuer Issuer value of the response + * @param status Status of the response (success, error, etc.) + * @param assertion SAML assertion to be included + * @return STORKResponse + */ + public static STORKResponse buildSTORKResponse( + String destination, + String inResponseTo, + Issuer issuer, + Status status, + Assertion assertion) { + + STORKResponse response = buildXMLObject(STORKResponse.DEFAULT_ELEMENT_NAME); + + response.setDestination(destination); + response.setInResponseTo(inResponseTo); + response.setConsent(STORKResponse.OBTAINED_CONSENT); + response.setID(generateID()); + response.setIssueInstant(new DateTime()); + response.setVersion(SAMLVersion.VERSION_20); + + response.setIssuer(issuer); + response.setStatus(status); + response.getAssertions().add(assertion); + + return response; + } + + /** + * Build STORKResponse + * @param destination Endpoint where the STORKResponse should be sent to + * @param inResponseTo ID of the corresponding AuthnRequest + * @param issuer Issuer value of the response + * @param status Status of the response (success, error, etc.) + * @param statusMessage Status message for the response + * @param assertion SAML assertion to be included + * @return STORKResponse + */ + public static STORKResponse buildSTORKResponse( + String destination, + String inResponseTo, + String issuerString, + String statusCode, + String statusMessage, + Assertion assertion) { + + Status status = buildStatus(statusCode, statusMessage); + Issuer issuer = buildIssuer(issuerString); + + return buildSTORKResponse(destination, inResponseTo, issuer, status, assertion); + } + + + /** + * Builds a STORKResponse containing no assertion + * @param destination Endpoint where the STORKResponse should be sent to + * @param inResponseTo ID of the corresponding AuthnRequest + * @param issuer Issuer value of the response + * @param status Status of the response (success, error, etc.) + * @param statusMessage Status message for the response + * @return STORKResponse + */ + public static STORKResponse buildSTORKErrorResponse( + String destination, + String inResponseTo, + String issuerString, + String statusCode, + String statusMessage) { + + return buildSTORKResponse(destination, inResponseTo, issuerString, statusCode, statusMessage, null); + } + + /** + * Builds Status object + * @param statusCodeValue StatusCode + * @param statusMessageValue StatusMessage + * @return Status + */ + public static Status buildStatus(String statusCodeValue, String statusMessageValue) { + return buildStatus(statusCodeValue, statusMessageValue, null); + } + + /** + * Builds Status object + * @param statusCodeValue StatusCode + * @param statusMessageValue StatusMessage + * @param detail Detail Message + * @return Status + */ + public static Status buildStatus(String statusCodeValue, String statusMessageValue, XMLObject detail) { + StatusCode statusCode = buildXMLObject(StatusCode.DEFAULT_ELEMENT_NAME); + statusCode.setValue(statusCodeValue); + + StatusMessage statusMessage = buildXMLObject(StatusMessage.DEFAULT_ELEMENT_NAME); + statusMessage.setMessage(statusMessageValue); + + StatusDetail statusDetail = buildXMLObject(StatusDetail.DEFAULT_ELEMENT_NAME); + statusDetail.getUnknownXMLObjects().add(detail); + + Status status = buildXMLObject(Status.DEFAULT_ELEMENT_NAME); + status.setStatusCode(statusCode); + status.setStatusMessage(statusMessage); + + return status; + + } + + /** + * Builds Assertion + * @param issuer Issuer value for assertion + * @param subject Subject of assertion + * @param conditions Conditions of assertion + * @param authnStatement AuthnStatement + * @param attributeStatement AttributeAtatement + * @return Assertion + */ + public static Assertion buildAssertion(Issuer issuer, + Subject subject, + Conditions conditions, + AuthnStatement authnStatement, + AttributeStatement attributeStatement) { + Assertion assertion = buildXMLObject(Assertion.DEFAULT_ELEMENT_NAME); + + assertion.setID(generateID()); + assertion.setVersion(SAMLVersion.VERSION_20); + assertion.setIssueInstant(new DateTime()); + + assertion.setIssuer(issuer); + assertion.setSubject(subject); + assertion.setConditions(conditions); + assertion.getAuthnStatements().add(authnStatement); + assertion.getAttributeStatements().add(attributeStatement); + + return assertion; + } + + /** + * Builds Assertion object + * @param issuerValue Value of the issuer + * @param nameQualifier nameQualifier + * @param spNameQualifier spNameQualifier + * @param spProviderID spProviderID + * @param ipAddress IP address of the client + * @param inResponseTo ID of the corresponding AuthnRequest + * @param notBefore Time before assertion is not valid + * @param notOnOrAfter Time after assertion is not valid + * @param recipient Recipient of the assertion + * @param attributeList Attributes to be included in the assertion + * @return Assertion + */ + public static Assertion buildAssertion( + String issuerValue, + String nameQualifier, + String spNameQualifier, + String spProviderID, + String ipAddress, + String inResponseTo, + DateTime notBefore, + DateTime notOnOrAfter, + String recipient, + List attributeList) { + + Issuer issuer = buildIssuer(issuerValue); + NameID nameID = buildNameID(NameID.UNSPECIFIED, nameQualifier, spNameQualifier, spProviderID, NameID.UNSPECIFIED); + SubjectConfirmationData scData = buildSubjectConfirmationData(ipAddress, inResponseTo, notOnOrAfter, recipient); + SubjectConfirmation subjectConfirmation = buildSubjectConfirmation(SubjectConfirmation.METHOD_BEARER, scData); + Subject subject = buildSubject(nameID, subjectConfirmation); + + List audienceList = buildAudienceList(recipient); + Conditions conditions = buildConditions(notBefore, notOnOrAfter, audienceList); + AuthnStatement authnStatement = buildAuthnStatement(ipAddress); + AttributeStatement attributeStatement = buildAttributeStatement(attributeList); + + return buildAssertion(issuer, subject, conditions, authnStatement, attributeStatement); + } + + /** + * Builds List of Audience objects + * @param audiences Audience strings + * @return List of Audience + */ + public static List buildAudienceList(String... audiences) { + List audienceList = new ArrayList(); + + for (String audienceString : audiences) { + Audience audience = buildXMLObject(Audience.DEFAULT_ELEMENT_NAME); + audience.setAudienceURI(audienceString); + audienceList.add(audience); + } + + return audienceList; + } + + /** + * Builds NameID object + * @param format Format of the NameID + * @param nameQualifier nameQualifier + * @param spNameQualifier spNameQualifier + * @param spProviderID spProviderID + * @param value Value of the NameID + * @return NameID + */ + public static NameID buildNameID(String format, + String nameQualifier, + String spNameQualifier, + String spProviderID, + String value) { + + NameID nameID = buildXMLObject(NameID.DEFAULT_ELEMENT_NAME); + + nameID.setFormat(format); + nameID.setNameQualifier(nameQualifier); + nameID.setSPNameQualifier(spNameQualifier); + nameID.setSPProvidedID(spProviderID); + nameID.setValue(value); + + return nameID; + + } + + /** + * Builds SubjectConfirmation object + * @param method Method of SubjectConfirmation + * @param scData SubjectConfirmationData + * @return SubjectConfirmation + */ + public static SubjectConfirmation buildSubjectConfirmation(String method, SubjectConfirmationData scData) { + + SubjectConfirmation subjectConfirmation = buildXMLObject(SubjectConfirmation.DEFAULT_ELEMENT_NAME); + + subjectConfirmation.setMethod(method); + subjectConfirmation.setSubjectConfirmationData(scData); + + return subjectConfirmation; + } + + /** + * Builds SubjectConfirmationData object + * @param ipAddress IP address of the client + * @param inResponseTo ID of the corresponding AuthnRequest + * @param notOnOrAfter Time after subject is not valid + * @param recipient recipient of the assertion + * @return SubjectConfirmationData + */ + public static SubjectConfirmationData buildSubjectConfirmationData(String ipAddress, + String inResponseTo, + DateTime notOnOrAfter, + String recipient) { + + SubjectConfirmationData scData = buildXMLObject(SubjectConfirmationData.DEFAULT_ELEMENT_NAME); + + scData.setAddress(ipAddress); + scData.setInResponseTo(inResponseTo); + scData.setNotOnOrAfter(notOnOrAfter); + scData.setRecipient(recipient); + + return scData; + + } + + /** + * Builds Subject object + * @param nameID NameID object + * @param subjectConfirmation SubjectConfirmation + * @return Subject + */ + public static Subject buildSubject(NameID nameID, SubjectConfirmation subjectConfirmation) { + + Subject subject = buildXMLObject(Subject.DEFAULT_ELEMENT_NAME); + subject.setNameID(nameID); + subject.getSubjectConfirmations().add(subjectConfirmation); + + return subject; + } + + /** + * Build Conditions object + * @param notBefore Time before assertion is not valid + * @param notOnOrAfter Time after assertion is not valid + * @param audienceList List of audience + * @return Conditions + */ + public static Conditions buildConditions(DateTime notBefore, DateTime notOnOrAfter, List audienceList) { + Conditions conditions = buildXMLObject(Conditions.DEFAULT_ELEMENT_NAME); + + conditions.setNotBefore(notBefore); + conditions.setNotOnOrAfter(notOnOrAfter); + + AudienceRestriction audienceRestriction = buildXMLObject(AudienceRestriction.DEFAULT_ELEMENT_NAME); + audienceRestriction.getAudiences().addAll(audienceList); + conditions.getAudienceRestrictions().add(audienceRestriction); + + OneTimeUse oneTimeUse = buildXMLObject(OneTimeUse.DEFAULT_ELEMENT_NAME); + conditions.getConditions().add(oneTimeUse); + + return conditions; + + } + + /** + * Build AuthnStatement object + * @param authInstant Time instant of authentication + * @param subjectLocality subjectLocality + * @param authnContext AuthnContext used + * @return AuthnStatement + */ + public static AuthnStatement buildAuthnStatement(DateTime authInstant, SubjectLocality subjectLocality, AuthnContext authnContext) { + AuthnStatement authnStatement = buildXMLObject(AuthnStatement.DEFAULT_ELEMENT_NAME); + + authnStatement.setAuthnInstant(authInstant); + authnStatement.setSubjectLocality(subjectLocality); + authnStatement.setAuthnContext(authnContext); + + return authnStatement; + } + + /** + * Build AuthnStatement object + * @param ipAddress IP address of the client + * @return AuthnStatement + */ + public static AuthnStatement buildAuthnStatement(String ipAddress) { + AuthnStatement authnStatement = buildXMLObject(AuthnStatement.DEFAULT_ELEMENT_NAME); + + authnStatement.setAuthnInstant(new DateTime()); + + SubjectLocality subjectLocality = buildXMLObject(SubjectLocality.DEFAULT_ELEMENT_NAME); + subjectLocality.setAddress(ipAddress); + authnStatement.setSubjectLocality(subjectLocality); + + AuthnContext authnContext = buildXMLObject(AuthnContext.DEFAULT_ELEMENT_NAME); + authnStatement.setAuthnContext(authnContext); + + return authnStatement; + } + + /** + * Builds AttributeStatement object + * @return AttributeStatement + */ + public static AttributeStatement buildAttributeStatement() { + return buildXMLObject(AttributeStatement.DEFAULT_ELEMENT_NAME); + } + + /** + * Builds AttributeStatement object + * @param attributeList List of attributes + * @return AttributeStatement + */ + public static AttributeStatement buildAttributeStatement(List attributeList) { + AttributeStatement attributeStatement = buildXMLObject(AttributeStatement.DEFAULT_ELEMENT_NAME); + attributeStatement.getAttributes().addAll(attributeList); + + return attributeStatement; + } + + /** + * Builds STORK String Attribute + * @param name Attribute Name + * @param friendlyName friendlyName of Attribute + * @param value Value of Attribute + * @param status STORK status of attribute + * @return STORK String Attribute + */ + public static Attribute buildSTORKStringAttribute(String name, String friendlyName, String value, String status) { + XSString xsString = buildXSString(AttributeValue.DEFAULT_ELEMENT_NAME); + xsString.setValue(value); + + return buildAttribute(name, friendlyName, status, xsString); + } + + /** + * Builds STORK XML Any Attribute + * @param name Attribute Name + * @param friendlyName friendlyName of Attribute + * @param value Value of Attribute + * @param status STORK status of attribute + * @return STORK XML Any Attribute + */ + public static Attribute buildSTORKXMLAttribute(String name, String friendlyName, XMLObject value, String status) { + XSAny xsAny = buildXMLObject(AttributeValue.DEFAULT_ELEMENT_NAME); + xsAny.getUnknownXMLObjects().add(value); + + return buildAttribute(name, friendlyName, status, xsAny); + } + + /** + * Builds STORK Attribute + * @param name Attribute Name + * @param friendlyName friendlyName of Attribute + * @param status STORK status of Attribute + * @param attributeValue Value of the Attribute + * @return Attribute + */ + public static Attribute buildAttribute(String name, String friendlyName, String status, XMLObject attributeValue) { + Attribute attribute = buildXMLObject(STORKAttribute.DEFAULT_ELEMENT_NAME); + + attribute.setNameFormat(STORKAttribute.URI_REFERENCE); + attribute.setFriendlyName(friendlyName); + attribute.setName(name); + attribute.getUnknownAttributes().put(STORKAttribute.DEFAULT_STORK_ATTRIBUTE_QNAME, status); + attribute.getAttributeValues().add(attributeValue); + + return attribute; + } + + /** + * Builds STORK String Attribute + * @param name Attribute Name + * @param friendlyName friendlyName of Attribute + * @param status STORK status of Attribute + * @param attributeValue Value of the Attribute + * @return String Attribute + */ + public static Attribute buildStringAttribute(String name, String friendlyName, String status, String attributeValue) { + Attribute attribute = buildXMLObject(STORKAttribute.DEFAULT_ELEMENT_NAME); + + attribute.setNameFormat(STORKAttribute.URI_REFERENCE); + attribute.setFriendlyName(friendlyName); + attribute.setName(name); + attribute.getUnknownAttributes().put(STORKAttribute.DEFAULT_STORK_ATTRIBUTE_QNAME, status); + + XSString xsString = buildXSString(AttributeValue.DEFAULT_ELEMENT_NAME); + xsString.setValue(attributeValue); + attribute.getAttributeValues().add(xsString); + + return attribute; + } + + /** + * Builds DSS signature request + * @param textToBeSigned Text to be included in the DSS request + * @param mimeType MimeType of the contents + * @return DSS signature request as String + */ + public static String buildSignatureRequestString(String textToBeSigned, String mimeType) { + //MimeType=\"text/plain\" + //MimeType=\"application/xhtml+xml\" + String sigRequestString = + "" + + "" + + "" + + "" + Base64.encodeBytes(textToBeSigned.getBytes()) + "" + + "" + + "" + + ""; + + return sigRequestString; + + } + + /** + * Builds STORK signedDoc RequestedAttribute + * @param textToBeSigned Text to be included in the DSS request + * @param mimeType MimeType of the contents + * @param isRequired true or false if signedDoc RequestedAttribute is required + * @return STORK signedDoc RequestedAttribute + */ + public static RequestedAttribute buildSignatureRequestRequestedAttribute(String textToBeSigned, String mimeType, boolean isRequired) { + return buildRequestedAttribute(STORKConstants.STORK_ATTRIBUTE_SIGNEDDOC, isRequired, buildSignatureRequestString(textToBeSigned, mimeType)); + } + + /** + * Adds RequestedAttribute to STORKAuthnRequest + * @param authnRequest STORKAuthnRequest + * @param reqAttr RequestedAttribute + */ + public static void addRequestedAttribute(STORKAuthnRequest authnRequest, RequestedAttribute reqAttr) { + if (authnRequest != null) { + RequestedAttributes requestedAttributes = (RequestedAttributes) authnRequest.getExtensions().getUnknownXMLObjects(RequestedAttributes.DEFAULT_ELEMENT_NAME).get(0); + requestedAttributes.getRequestedAttributes().add(reqAttr); + } + } + + /** + * Adds several RequestedAttribute to STORKAuthnRequest + * @param authnRequest STORKAuthnRequest + * @param reqAttr RequestedAttribute + */ + public static void addRequestedAttributes(STORKAuthnRequest authnRequest, RequestedAttribute... reqAttrs) { + for (RequestedAttribute reqAttr : reqAttrs) { + addRequestedAttribute(authnRequest, reqAttr); + } + } + + /** + * Builds STORK signed doc attribute and adds it to STORKAuthnRequest + * @param authnRequest STORKAuthnRequest + * @param textToBeSigned Text to be included in the DSS request + * @param mimeType MimeType of the contents + * @param isRequired true or false if signedDoc RequestedAttribute is required + */ + public static void buildAndAddSignatureRequestToAuthnRequest(STORKAuthnRequest authnRequest, String textToBeSigned, String mimeType, boolean isRequired) { + if (authnRequest != null && !StringUtils.isEmpty(textToBeSigned)) { + addRequestedAttribute(authnRequest, buildSignatureRequestRequestedAttribute(textToBeSigned, mimeType, isRequired)); + } + + } + + /** + * Adds DSS siganture request as String to STORKAuthnRequest + * @param authnRequest STORKAuthnRequest + * @param dssSignatureRequest DSS signature request as String + * @param isRequired true or false if signedDoc RequestedAttribute is required + */ + public static void addSignatureRequestToAuthnRequest(STORKAuthnRequest authnRequest, String dssSignatureRequest, boolean isRequired) { + if (authnRequest != null && !StringUtils.isEmpty(dssSignatureRequest)) { + addRequestedAttribute(authnRequest, buildRequestedAttribute(STORKConstants.STORK_ATTRIBUTE_SIGNEDDOC, isRequired, dssSignatureRequest)); + } + + } + + /** + * Adds Attribute to an assertion + * @param assertion Assertion + * @param attr Attribute + */ + public static void addAttribute(Assertion assertion, Attribute attr) { + if (assertion != null) { + if (!assertion.getAttributeStatements().isEmpty()) { + assertion.getAttributeStatements().get(0).getAttributes().add(attr); + } + } + } + + /** + * Adds several Attribute to an assertion + * @param assertion Assertion + * @param attr Attribute + */ + public static void addAttributes(Assertion assertion, Attribute... attrs) { + for (Attribute attr : attrs) { + addAttribute(assertion, attr); + } + } + + /** + * Adds several Attribute to first assertion in STORK response + * @param response STORK response + * @param attrs Attribute + */ + public static void addAttribute(STORKResponse response, Attribute... attrs) { + if (response != null) { + if (!response.getAssertions().isEmpty()) { + addAttributes(response.getAssertions().get(0), attrs); + } + } + } + +} -- cgit v1.2.3