diff options
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/PVP2AssertionBuilder.java')
-rw-r--r-- | eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/PVP2AssertionBuilder.java | 459 |
1 files changed, 0 insertions, 459 deletions
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/PVP2AssertionBuilder.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/PVP2AssertionBuilder.java deleted file mode 100644 index 2ccc2c9e..00000000 --- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/builder/PVP2AssertionBuilder.java +++ /dev/null @@ -1,459 +0,0 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder; - -import java.security.MessageDigest; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.opensaml.common.xml.SAMLConstants; -import org.opensaml.saml2.core.Assertion; -import org.opensaml.saml2.core.Attribute; -import org.opensaml.saml2.core.AttributeQuery; -import org.opensaml.saml2.core.AttributeStatement; -import org.opensaml.saml2.core.Audience; -import org.opensaml.saml2.core.AudienceRestriction; -import org.opensaml.saml2.core.AuthnContext; -import org.opensaml.saml2.core.AuthnContextClassRef; -import org.opensaml.saml2.core.AuthnRequest; -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.RequestedAuthnContext; -import org.opensaml.saml2.core.Subject; -import org.opensaml.saml2.core.SubjectConfirmation; -import org.opensaml.saml2.core.SubjectConfirmationData; -import org.opensaml.saml2.core.impl.AuthnRequestImpl; -import org.opensaml.saml2.metadata.AssertionConsumerService; -import org.opensaml.saml2.metadata.AttributeConsumingService; -import org.opensaml.saml2.metadata.EntityDescriptor; -import org.opensaml.saml2.metadata.NameIDFormat; -import org.opensaml.saml2.metadata.RequestedAttribute; -import org.opensaml.saml2.metadata.SPSSODescriptor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.Base64Utils; - -import at.gv.egiz.eaaf.core.api.data.EAAFConstants; -import at.gv.egiz.eaaf.core.api.data.ILoALevelMapper; -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.slo.SLOInformationInterface; -import at.gv.egiz.eaaf.core.exceptions.UnavailableAttributeException; -import at.gv.egiz.eaaf.core.impl.data.Pair; -import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl; -import at.gv.egiz.eaaf.core.impl.utils.Random; -import at.gv.egiz.eaaf.modules.pvp2.PVPConstants; -import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception; -import at.gv.egiz.eaaf.modules.pvp2.exception.QAANotSupportedException; -import at.gv.egiz.eaaf.modules.pvp2.idp.api.builder.ISubjectNameIdGenerator; -import at.gv.egiz.eaaf.modules.pvp2.idp.exception.ResponderErrorException; -import at.gv.egiz.eaaf.modules.pvp2.idp.exception.UnprovideableAttributeException; -import at.gv.egiz.eaaf.modules.pvp2.idp.impl.PVPSProfilePendingRequest; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PVPAttributeBuilder; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.QAALevelVerifier; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils; - -@Service("PVP2AssertionBuilder") -public class PVP2AssertionBuilder implements PVPConstants { - - private static final Logger log = LoggerFactory.getLogger(PVP2AssertionBuilder.class); - @Autowired private ILoALevelMapper loaLevelMapper; - @Autowired private ISubjectNameIdGenerator subjectNameIdGenerator; - - - /** - * Build a PVP assertion as response for a SAML2 AttributeQuery request - * - * @param issuerEntityID EnitiyID, which should be used for this IDP response - * @param attrQuery AttributeQuery request from Service-Provider - * @param attrList List of PVP response attributes - * @param now Current time - * @param validTo ValidTo time of the assertion - * @param qaaLevel QAA level of the authentication - * @param sessionIndex SAML2 SessionIndex, which should be included * - * @return PVP 2.1 Assertion - * @throws PVP2Exception - */ - public Assertion buildAssertion(String issuerEntityID, AttributeQuery attrQuery, - List<Attribute> attrList, DateTime now, DateTime validTo, String qaaLevel, String sessionIndex) throws PVP2Exception { - - AuthnContextClassRef authnContextClassRef = SAML2Utils.createSAMLObject(AuthnContextClassRef.class); - authnContextClassRef.setAuthnContextClassRef(qaaLevel); - - NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class); - subjectNameID.setFormat(attrQuery.getSubject().getNameID().getFormat()); - subjectNameID.setValue(attrQuery.getSubject().getNameID().getValue()); - - SubjectConfirmationData subjectConfirmationData = null; - - return buildGenericAssertion(issuerEntityID, attrQuery.getIssuer().getValue(), now, - authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex, - validTo); - } - - - /** - * Build a PVP 2.1 assertion as response of a SAML2 AuthnRequest - * - * @param issuerEntityID EnitiyID, which should be used for this IDP response - * @param pendingReq Current processed pendingRequest DAO - * @param authnRequest Current processed PVP AuthnRequest - * @param authData AuthenticationData of the user, which is already authenticated - * @param peerEntity SAML2 EntityDescriptor of the service-provider, which receives the response - * @param date TimeStamp - * @param assertionConsumerService SAML2 endpoint of the service-provider, which should be used - * @param sloInformation Single LogOut information DAO - * @return - * @throws PVP2Exception - */ - public Assertion buildAssertion(String issuerEntityID, PVPSProfilePendingRequest pendingReq, AuthnRequest authnRequest, - IAuthData authData, EntityDescriptor peerEntity, DateTime date, - AssertionConsumerService assertionConsumerService, SLOInformationInterface sloInformation) - throws PVP2Exception { - - ISPConfiguration oaParam = pendingReq.getServiceProviderConfiguration(); - AuthnContextClassRef authnContextClassRef = SAML2Utils.createSAMLObject(AuthnContextClassRef.class); - - //check if authn. request contains LoA - RequestedAuthnContext reqAuthnContext = authnRequest.getRequestedAuthnContext(); - if (reqAuthnContext == null) { - authnContextClassRef.setAuthnContextClassRef(authData.getEIDASQAALevel()); - - } else { - //authn. request requests LoA levels. To LoA validation - List<AuthnContextClassRef> reqAuthnContextClassRefIt = reqAuthnContext.getAuthnContextClassRefs(); - - //get matching mode from authn. request - String loaMatchingMode = EAAFConstants.EIDAS_LOA_MATCHING_MINIMUM; - if (reqAuthnContext.getComparison() != null && - StringUtils.isNotEmpty(reqAuthnContext.getComparison().toString())) - loaMatchingMode = reqAuthnContext.getComparison().toString(); - - //get requested LoAs - if (reqAuthnContextClassRefIt.size() == 0) { - QAALevelVerifier.verifyQAALevel(authData.getEIDASQAALevel(), - oaParam.getRequiredLoA(), loaMatchingMode); - authnContextClassRef.setAuthnContextClassRef(authData.getEIDASQAALevel()); - - } else { - List<String> eIDASLoaFromRequest = new ArrayList<String>(); - for (AuthnContextClassRef authnClassRef : reqAuthnContextClassRefIt) { - String qaa_uri = authnClassRef.getAuthnContextClassRef(); - - if (!qaa_uri.trim().startsWith(EAAFConstants.EIDAS_LOA_PREFIX)) { - if (loaLevelMapper != null) { - log.debug("Find no eIDAS LoA in AuthnReq. Start mapping process ... " ); - eIDASLoaFromRequest.add(loaLevelMapper.mapToeIDASLoA(qaa_uri.trim())); - - } else - log.debug("AuthnRequest contains no eIDAS LoA. NO LoA mapper FOUND, ignore " - + "'" + qaa_uri.trim() + "'"); - } else - eIDASLoaFromRequest.add(qaa_uri.trim()); - - } - - //stop process if no supported LoA scheme is requested - if (eIDASLoaFromRequest.isEmpty()) { - log.info("Authn. request contains no supported LoA level. Stop authentication process ... "); - throw new QAANotSupportedException("No supported LoA in Authn. request"); - - } - - //verifiy LoAs from request to authentication LoA - QAALevelVerifier.verifyQAALevel(authData.getEIDASQAALevel(), eIDASLoaFromRequest , loaMatchingMode); - authnContextClassRef.setAuthnContextClassRef(authData.getEIDASQAALevel()); - - } - } - - - //load SPSS decriptor from service-provider metadata - SPSSODescriptor spSSODescriptor = peerEntity.getSPSSODescriptor(SAMLConstants.SAML20P_NS); - - //add Attributes to Assertion - List<Attribute> attrList = new ArrayList<Attribute>(); - if (spSSODescriptor.getAttributeConsumingServices() != null && - spSSODescriptor.getAttributeConsumingServices().size() > 0) { - - Integer aIdx = authnRequest.getAttributeConsumingServiceIndex(); - int idx = 0; - - AttributeConsumingService attributeConsumingService = null; - if (aIdx != null) { - idx = aIdx.intValue(); - attributeConsumingService = spSSODescriptor - .getAttributeConsumingServices().get(idx); - - } else { - List<AttributeConsumingService> attrConsumingServiceList = spSSODescriptor.getAttributeConsumingServices(); - for (AttributeConsumingService el : attrConsumingServiceList) { - if (el.isDefault()) - attributeConsumingService = el; - } - } - - /* - * TODO: maybe use first AttributeConsumingService if no is selected - * in request or on service is marked as default - * - */ - if (attributeConsumingService == null ) { - List<AttributeConsumingService> attrConsumingServiceList = spSSODescriptor.getAttributeConsumingServices(); - if (attrConsumingServiceList != null && !attrConsumingServiceList.isEmpty()) - attributeConsumingService = attrConsumingServiceList.get(0); - - } - - - if (attributeConsumingService != null) { - Iterator<RequestedAttribute> it = attributeConsumingService - .getRequestAttributes().iterator(); - while (it.hasNext()) { - RequestedAttribute reqAttribut = it.next(); - try { - Attribute attr = PVPAttributeBuilder.buildAttribute( - reqAttribut.getName(), oaParam, authData); - if (attr == null) { - if (reqAttribut.isRequired()) { - throw new UnprovideableAttributeException( - reqAttribut.getName()); - } - } else { - attrList.add(attr); - } - - } catch (UnavailableAttributeException e) { - log.info( - "Attribute generation for " - + reqAttribut.getFriendlyName() + " not possible."); - if (reqAttribut.isRequired()) { - throw new UnprovideableAttributeException( - reqAttribut.getName()); - } - - - } catch (PVP2Exception e) { - log.info( - "Attribute generation failed! for " - + reqAttribut.getFriendlyName()); - if (reqAttribut.isRequired()) { - throw new UnprovideableAttributeException( - reqAttribut.getName()); - } - - } catch (Exception e) { - log.warn( - "General Attribute generation failed! for " - + reqAttribut.getFriendlyName(), e); - if (reqAttribut.isRequired()) { - throw new UnprovideableAttributeException( - reqAttribut.getName()); - } - - } - } - } - } - - //generate subjectNameId - NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class); - Pair<String, String> subjectNameIdPair = subjectNameIdGenerator.generateSubjectNameId(authData, oaParam); - subjectNameID.setValue(subjectNameIdPair.getFirst()); - subjectNameID.setNameQualifier(subjectNameIdPair.getSecond()); - - //get NameIDFormat from request - String nameIDFormat = NameID.TRANSIENT; - AuthnRequest authnReq = (AuthnRequestImpl) authnRequest; - if (authnReq.getNameIDPolicy() != null && - StringUtils.isNotEmpty(authnReq.getNameIDPolicy().getFormat())) { - nameIDFormat = authnReq.getNameIDPolicy().getFormat(); - - } else { - //get NameIDFormat from metadata - List<NameIDFormat> metadataNameIDFormats = spSSODescriptor.getNameIDFormats(); - - if (metadataNameIDFormats != null) { - - for (NameIDFormat el : metadataNameIDFormats) { - if (NameID.PERSISTENT.equals(el.getFormat())) { - nameIDFormat = NameID.PERSISTENT; - break; - - } else if (NameID.TRANSIENT.equals(el.getFormat()) || - NameID.UNSPECIFIED.equals(el.getFormat())) - break; - - } - } - } - - if (NameID.TRANSIENT.equals(nameIDFormat) || NameID.UNSPECIFIED.equals(nameIDFormat)) { - String random = Random.nextHexRandom32(); - String nameID = subjectNameID.getValue(); - - try { - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest((nameID + random).getBytes("ISO-8859-1")); - subjectNameID.setValue(Base64Utils.encodeToString(hash)); - subjectNameID.setNameQualifier(null); - subjectNameID.setFormat(NameID.TRANSIENT); - - } catch (Exception e) { - log.warn("PVP2 subjectNameID error", e); - throw new ResponderErrorException("internal.03", null, e); - - } - - } else - subjectNameID.setFormat(nameIDFormat); - - - String sessionIndex = null; - - //if request is a reauthentication and NameIDFormat match reuse old session information - if (StringUtils.isNotEmpty(authData.getNameID()) && - StringUtils.isNotEmpty(authData.getNameIDFormat()) && - nameIDFormat.equals(authData.getNameIDFormat())) { - subjectNameID.setValue(authData.getNameID()); - sessionIndex = authData.getSessionIndex(); - - } - - // - if (StringUtils.isEmpty(sessionIndex)) - sessionIndex = SAML2Utils.getSecureIdentifier(); - - SubjectConfirmationData subjectConfirmationData = SAML2Utils - .createSAMLObject(SubjectConfirmationData.class); - subjectConfirmationData.setInResponseTo(authnRequest.getID()); - subjectConfirmationData.setNotOnOrAfter(new DateTime(authData.getSsoSessionValidTo().getTime())); - - //set 'recipient' attribute in subjectConformationData - subjectConfirmationData.setRecipient(assertionConsumerService.getLocation()); - - //set IP address of the user machine as 'Address' attribute in subjectConformationData - String usersIPAddress = pendingReq.getRawData( - RequestImpl.DATAID_REQUESTER_IP_ADDRESS, String.class); - if (StringUtils.isNotEmpty(usersIPAddress)) - subjectConfirmationData.setAddress(usersIPAddress); - - //set SLO information - sloInformation.setUserNameIdentifier(subjectNameID.getValue()); - sloInformation.setNameIDFormat(subjectNameID.getFormat()); - sloInformation.setSessionIndex(sessionIndex); - - return buildGenericAssertion(issuerEntityID, peerEntity.getEntityID(), date, authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex, subjectConfirmationData.getNotOnOrAfter()); - } - - /** - * - * @param issuer IDP EntityID - * @param entityID Service Provider EntityID - * @param date - * @param authnContextClassRef - * @param attrList - * @param subjectNameID - * @param subjectConfirmationData - * @param sessionIndex - * @param isValidTo - * @return - * @throws ConfigurationException - */ - - public Assertion buildGenericAssertion(String issuer, String entityID, DateTime date, - AuthnContextClassRef authnContextClassRef, List<Attribute> attrList, - NameID subjectNameID, SubjectConfirmationData subjectConfirmationData, - String sessionIndex, DateTime isValidTo) throws ResponderErrorException { - Assertion assertion = SAML2Utils.createSAMLObject(Assertion.class); - - AuthnContext authnContext = SAML2Utils - .createSAMLObject(AuthnContext.class); - authnContext.setAuthnContextClassRef(authnContextClassRef); - - AuthnStatement authnStatement = SAML2Utils - .createSAMLObject(AuthnStatement.class); - - authnStatement.setAuthnInstant(date); - authnStatement.setSessionIndex(sessionIndex); - authnStatement.setAuthnContext(authnContext); - - assertion.getAuthnStatements().add(authnStatement); - - AttributeStatement attributeStatement = SAML2Utils - .createSAMLObject(AttributeStatement.class); - attributeStatement.getAttributes().addAll(attrList); - if (attributeStatement.getAttributes().size() > 0) { - assertion.getAttributeStatements().add(attributeStatement); - } - - Subject subject = SAML2Utils.createSAMLObject(Subject.class); - subject.setNameID(subjectNameID); - - SubjectConfirmation subjectConfirmation = SAML2Utils - .createSAMLObject(SubjectConfirmation.class); - subjectConfirmation.setMethod(SubjectConfirmation.METHOD_BEARER); - subjectConfirmation.setSubjectConfirmationData(subjectConfirmationData); - - subject.getSubjectConfirmations().add(subjectConfirmation); - - Conditions conditions = SAML2Utils.createSAMLObject(Conditions.class); - AudienceRestriction audienceRestriction = SAML2Utils - .createSAMLObject(AudienceRestriction.class); - Audience audience = SAML2Utils.createSAMLObject(Audience.class); - - audience.setAudienceURI(entityID); - audienceRestriction.getAudiences().add(audience); - conditions.setNotBefore(date); - conditions.setNotOnOrAfter(isValidTo); - - conditions.getAudienceRestrictions().add(audienceRestriction); - - assertion.setConditions(conditions); - - Issuer issuerObj = SAML2Utils.createSAMLObject(Issuer.class); - - if (issuer.endsWith("/")) - issuer = issuer.substring(0, issuer.length()-1); - issuerObj.setValue(issuer); - issuerObj.setFormat(NameID.ENTITY); - - assertion.setIssuer(issuerObj); - assertion.setSubject(subject); - assertion.setID(SAML2Utils.getSecureIdentifier()); - assertion.setIssueInstant(date); - - return assertion; - } -} |