diff options
author | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2018-07-20 10:56:04 +0200 |
---|---|---|
committer | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2018-07-20 10:56:04 +0200 |
commit | 31bc1246bb56fcd8807678e3f7516023bdfaed44 (patch) | |
tree | 0c3ed662a5be943a4ceb70d021e1bb7ac9dc1015 /eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/validator | |
parent | 2945c875bda2c8236d0b3fd630358fcaca85f4a8 (diff) | |
download | National_eIDAS_Gateway-31bc1246bb56fcd8807678e3f7516023bdfaed44.tar.gz National_eIDAS_Gateway-31bc1246bb56fcd8807678e3f7516023bdfaed44.tar.bz2 National_eIDAS_Gateway-31bc1246bb56fcd8807678e3f7516023bdfaed44.zip |
add SZR client
add different logging backends
define errorcodes and error messages
update to eIDAS Ref. impl 2.1
Diffstat (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/validator')
-rw-r--r-- | eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java new file mode 100644 index 00000000..3791d0d7 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java @@ -0,0 +1,135 @@ +package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.validator; + +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.ImmutableList; + +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.impl.data.Trible; +import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.Constants; +import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASValidationException; +import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.service.eIDASAttributeRegistry; +import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.utils.eIDASResponseUtils; +import eu.eidas.auth.commons.attribute.AttributeDefinition; +import eu.eidas.auth.commons.attribute.AttributeValue; +import eu.eidas.auth.commons.light.ILightResponse; +import eu.eidas.auth.commons.protocol.eidas.LevelOfAssurance; + +/** + * @author tlenz + * + */ +public class eIDASResponseValidator { + private static final Logger log = LoggerFactory.getLogger(eIDASResponseValidator.class); + + public static void validateResponse(IRequest pendingReq, ILightResponse eIDASResponse, String spCountry, eIDASAttributeRegistry attrRegistry) throws eIDASValidationException { + + /*-----------------------------------------------------| + * validate received LoA against minimum required LoA | + *_____________________________________________________| + */ + LevelOfAssurance respLoA = LevelOfAssurance.fromString(eIDASResponse.getLevelOfAssurance()); + List<String> allowedLoAs = pendingReq.getServiceProviderConfiguration().getRequiredLoA(); + boolean loaValid = false; + for (String allowedLoaString : allowedLoAs) { + LevelOfAssurance allowedLoa = LevelOfAssurance.fromString(allowedLoaString); + if (respLoA.numericValue() >= allowedLoa.numericValue()) { + log.debug("Response contains valid LoA. Resume process ... "); + loaValid = true; + break; + + } else + log.trace("Allowed LoA: " + allowedLoaString + " DOES NOT match response LoA: " + eIDASResponse.getLevelOfAssurance()); + + } + + if (!loaValid) { + log.error("eIDAS Response LevelOfAssurance is lower than the required! " + + "(Resp-LoA:" + respLoA.getValue() + " Req-LoA:" + allowedLoAs.toArray() + ")"); + throw new eIDASValidationException("eidas.06", new Object[]{respLoA.getValue()}); + + } + + + + /*-----------------------------------------------------| + * validate 'PersonalIdentifier' attribute | + *_____________________________________________________| + */ + AttributeDefinition<?> attrDefinition = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); + final ImmutableList<? extends AttributeValue<?>> attributeValues = eIDASResponse.getAttributes().getAttributeMap().get(attrDefinition).asList(); + List<String> personalIdObj = eIDASResponseUtils.translateStringListAttribute(attrDefinition, attributeValues); + + //check if attribute exists + if (personalIdObj == null || personalIdObj.isEmpty()) { + log.warn("eIDAS Response include NO 'PersonalIdentifier' attriubte " + + ".... That can be a BIG problem in further processing steps"); + throw new eIDASValidationException("eidas.05", new Object[] {"NO 'PersonalIdentifier' attriubte"}); + + } else if (personalIdObj.size() > 1) { + log.warn("eIDAS Response include MORE THAN ONE 'PersonalIdentifier' attriubtes " + + ".... That can be a BIG problem in further processing steps"); + throw new eIDASValidationException("eidas.05", new Object[] {"MORE THAN ONE 'PersonalIdentifier' attriubtes"}); + + } else { + String natPersId = personalIdObj.get(0); + //validate attribute value format + Trible<String, String, String> split = + eIDASResponseUtils.parseEidasPersonalIdentifier(natPersId); + if (split == null) { + throw new eIDASValidationException("eidas.07", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "Wrong identifier format"}); + + } else { + //validation according to eIDAS SAML Attribute Profile, Section 2.2.3 + if (StringUtils.isEmpty(split.getSecond())) { + log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " includes NO destination country. Value:" + natPersId); + throw new eIDASValidationException("eidas.07", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "No or empty destination country"}); + + } + if (!split.getSecond().equalsIgnoreCase(spCountry)) { + log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " includes wrong destination country. Value:" + natPersId + + " SP-Country:" + spCountry); + throw new eIDASValidationException("eidas.07", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "Destination country does not match to SP country"}); + + } + + if (StringUtils.isEmpty(split.getFirst())) { + log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " includes NO citizen country. Value:" + natPersId); + throw new eIDASValidationException("eidas.07", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "No or empty citizen country"}); + + } + if (!split.getSecond().equalsIgnoreCase(spCountry)) { + log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " includes a relaying-party country that does not match to service-provider country. " + + " Value:" + natPersId + + " SP Country:" + spCountry); + throw new eIDASValidationException("eidas.07", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "Citizen country does not match to eIDAS-node country that generates the response"}); + + } + } + } + + } +} |