package at.gv.egovernment.moa.id.auth.modules.eIDAScentralAuth.semper; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.opensaml.saml2.core.AuthnRequest; import org.opensaml.saml2.metadata.SPSSODescriptor; import org.opensaml.xml.XMLObject; import org.springframework.beans.factory.annotation.Autowired; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.data.EAAFConstants; import at.gv.egiz.eaaf.core.api.data.ExtendedPVPAttributeDefinitions; import at.gv.egiz.eaaf.core.api.data.PVPAttributeDefinitions; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException; import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttribute; import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttributes; import at.gv.egiz.eaaf.modules.pvp2.api.validation.IAuthnRequestPostProcessor; import at.gv.egovernment.moa.id.auth.modules.eIDAScentralAuth.EidasCentralAuthConstants; import at.gv.egovernment.moa.id.commons.MOAIDConstants; import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants; import at.gv.egovernment.moa.logging.Logger; public class AuthnRequestSemperProcessor implements IAuthnRequestPostProcessor { @Autowired IConfiguration authConfig; @Override public void process(HttpServletRequest httpReq, IRequest pendingReq, AuthnRequest authReq, SPSSODescriptor spSsoDescriptor) throws AuthnRequestValidatorException { if (authConfig.getBasicConfigurationBoolean( EidasCentralAuthConstants.CONFIG_PROPS_SEMPER_MANDATES_ACTIVE, false) && isSpAllowed(authReq)) { Logger.debug("SEMPER mode detected. Starting SP-Info extraction from requested attributes ..."); extractRequestedAttributeInformation(authReq, pendingReq); } else { Logger.trace("Skip: " + AuthnRequestSemperProcessor.class.getSimpleName() + " because is's not active or not allowed"); } } private boolean isSpAllowed(AuthnRequest authReq) { String csvOfAllowedProxies = authConfig.getBasicConfiguration(EidasCentralAuthConstants.CONFIG_PROPS_SEMPER_MANDATES_MS_PROXY_LIST); List allowedProxies = KeyValueUtils.getListOfCSVValues(csvOfAllowedProxies); Logger.trace("Validate SP-EntityId: " + authReq.getIssuer().getValue() + " with allowed MS-Proxies: [" + StringUtils.join(allowedProxies, ", ") + "]"); return allowedProxies.contains(authReq.getIssuer().getValue()); } private void extractRequestedAttributeInformation(AuthnRequest authnReq, IRequest pendingReq) throws AuthnRequestValidatorException { // validate and process requested attributes boolean hasValidBpkTarget = false; if (authnReq.getExtensions() != null) { final List requestedAttributes = authnReq.getExtensions().getUnknownXMLObjects(); for (final XMLObject reqAttrObj : requestedAttributes) { if (reqAttrObj instanceof EAAFRequestedAttributes) { final EAAFRequestedAttributes reqAttr = (EAAFRequestedAttributes) reqAttrObj; if (reqAttr.getAttributes() != null && reqAttr.getAttributes().size() != 0) { for (final EAAFRequestedAttribute el : reqAttr.getAttributes()) { Logger.trace("Processing req. attribute '" + el.getName() + "' ... "); if (el.getName().equals(PVPAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME)) { hasValidBpkTarget = extractBpkTarget(el, pendingReq); } else if (el.getName().equals(ExtendedPVPAttributeDefinitions.SP_USESMANDATES_NAME )) { extractMandateProfiles(el, pendingReq); } else { Logger.debug("Ignore req. attribute: " + el.getName()); } } } else { Logger.debug("No requested Attributes in Authn. Request"); } } else { Logger.info("Ignore unknown requested attribute: " + reqAttrObj.getElementQName().toString()); } } } if (!hasValidBpkTarget) { Logger.info("Authn.Req validation FAILED. Reason: Contains NO or NO VALID target-sector information."); throw new AuthnRequestValidatorException("pvp2.22", new Object[] { "NO or NO VALID target-sector information" }); } } private void extractMandateProfiles(EAAFRequestedAttribute el, IRequest pendingReq) { if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) { final String profiles = el.getAttributeValues().get(0).getDOM().getTextContent(); Map configProps = pendingReq.getServiceProviderConfiguration().getFullConfiguration(); Logger.debug("Set MandateProfiles to: " + profiles); configProps.put( MOAIDConfigurationConstants.SERVICE_AUTH_MANDATES_OVS_USE, String.valueOf(true)); configProps.put( MOAIDConfigurationConstants.SERVICE_AUTH_MANDATES_OVS_PROFILES, profiles); } else { Logger.info("Req. attribute '" + el.getName() + "' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute"); } } private boolean extractBpkTarget(final EAAFRequestedAttribute el, IRequest pendingReq) { if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) { final String sectorId = el.getAttributeValues().get(0).getDOM().getTextContent(); Map configProps = pendingReq.getServiceProviderConfiguration().getFullConfiguration(); if (sectorId.startsWith(EAAFConstants.URN_PREFIX_EIDAS)) { Logger.debug("Set eIDAS target to: " + sectorId); configProps.put( MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_TYPE, MOAIDConstants.IDENIFICATIONTYPE_EIDAS); configProps.put(MOAIDConfigurationConstants.SERVICE_AUTH_TARGET_BUSINESS_VALUE, sectorId.substring(EAAFConstants.URN_PREFIX_EIDAS.length())); return true; } else { Logger.info("Requested sector: " + sectorId + " DOES NOT match to allowed sectors for SP: " + pendingReq.getServiceProviderConfiguration().getUniqueIdentifier()); } } else { Logger.info("Req. attribute '" + el.getName() + "' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute"); } return false; } }