aboutsummaryrefslogtreecommitdiff
path: root/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2020-11-27 09:08:10 +0100
committerThomas Lenz <thomas.lenz@egiz.gv.at>2020-11-27 09:08:10 +0100
commit7a62a84f23b3a1a1027ebda31fb790ee072793cc (patch)
tree7cf1804c99a2876abc934443a2cbfd8d4f59e99b /connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java
parentd01abea064f33d1c985464aadf3e2326c6ba3219 (diff)
downloadNational_eIDAS_Gateway-7a62a84f23b3a1a1027ebda31fb790ee072793cc.tar.gz
National_eIDAS_Gateway-7a62a84f23b3a1a1027ebda31fb790ee072793cc.tar.bz2
National_eIDAS_Gateway-7a62a84f23b3a1a1027ebda31fb790ee072793cc.zip
read unique transactionId from AuthnRequest to reuse it for eIDAS authentication
Diffstat (limited to 'connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java')
-rw-r--r--connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java247
1 files changed, 154 insertions, 93 deletions
diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java
index 26176c49..a9eb06be 100644
--- a/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java
+++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java
@@ -46,11 +46,13 @@ import at.asitplus.eidas.specific.connector.MsEidasNodeConstants;
import at.asitplus.eidas.specific.connector.config.ServiceProviderConfiguration;
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.exceptions.EaafException;
import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
+import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
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;
@@ -107,120 +109,179 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor {
}
// post-process requested LoA
- final List<String> reqLoA = extractLoA(authnReq);
- log.trace("SP requests LoA with: {}", String.join(", ",reqLoA));
+ postprocessLoaLevel(pendingReq, authnReq);
+
+ // post-process requested LoA comparison-level
+ pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).setLoAMachtingMode(
+ extractComparisonLevel(authnReq));
+
+ //extract information from requested attributes
+ extractFromRequestedAttriutes(pendingReq, authnReq);
- LevelOfAssurance minimumLoAFromConfig = LevelOfAssurance.fromString(basicConfig.getBasicConfiguration(
- MsEidasNodeConstants.PROP_EIDAS_REQUEST_LOA_MINIMUM_LEVEL,
- EaafConstants.EIDAS_LOA_HIGH));
- if (minimumLoAFromConfig == null) {
- log.warn("Can not load minimum LoA from configuration. Use LoA: {} as default",
- EaafConstants.EIDAS_LOA_HIGH);
- minimumLoAFromConfig = LevelOfAssurance.HIGH;
+ } catch (final EaafStorageException e) {
+ log.info("Can NOT store Authn. Req. data into pendingRequest.", e);
+ throw new AuthnRequestValidatorException("internal.02", null, e);
- }
-
- log.trace("Validate requested LoA to connector configuration minimum LoA: {} ...",
- minimumLoAFromConfig);
- final List<String> allowedLoA = new ArrayList<>();
- for (final String loa : reqLoA) {
- try {
- final LevelOfAssurance intLoa = LevelOfAssurance.fromString(loa);
- String selectedLoA = EaafConstants.EIDAS_LOA_HIGH;
- if (intLoa != null
- && intLoa.numericValue() <= minimumLoAFromConfig.numericValue()) {
- log.info("Client: {} requested LoA: {} will be upgraded to: {}",
- pendingReq.getServiceProviderConfiguration().getUniqueIdentifier(),
- loa,
- minimumLoAFromConfig);
- selectedLoA = minimumLoAFromConfig.getValue();
+ }
- }
+ }
- if (!allowedLoA.contains(selectedLoA)) {
- log.debug("Allow LoA: {} for Client: {}",
- selectedLoA,
- pendingReq.getServiceProviderConfiguration().getUniqueIdentifier());
- allowedLoA.add(selectedLoA);
+ private void extractFromRequestedAttriutes(IRequest pendingReq, AuthnRequest authnReq)
+ throws AuthnRequestValidatorException {
+ // validate and process requested attributes
+ boolean sectorDetected = false;
+
+ final ServiceProviderConfiguration spConfig = pendingReq.getServiceProviderConfiguration(
+ ServiceProviderConfiguration.class);
+
+ if (authnReq.getExtensions() != null) {
+ final List<XMLObject> 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()) {
+ log.trace("Processing req. attribute '" + el.getName() + "' ... ");
+ if (el.getName().equals(PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME)) {
+ sectorDetected = extractBpkTargetIdentifier(el, spConfig);
+
+ } else if (el.getName().equals(ExtendedPvpAttributeDefinitions.EID_TRANSACTION_ID_NAME)) {
+ extractUniqueTransactionId(el, pendingReq);
+
+ } else {
+ log.debug("Ignore req. attribute: " + el.getName());
+
+ }
+ }
+ } else {
+ log.debug("No requested Attributes in Authn. Request");
+
}
- } catch (final IllegalArgumentException e) {
- log.warn("LoA: {} is currently NOT supported and it will be ignored.", loa);
-
+ } else {
+ log.info("Ignore unknown requested attribute: " + reqAttrObj.getElementQName().toString());
+
}
-
}
+ }
+
+ if (!sectorDetected) {
+ log.warn("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" });
- pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).setRequiredLoA(
- allowedLoA);
+ }
+
+ }
- // post-process requested LoA comparison-level
- final String reqLoAComperison = extractComparisonLevel(authnReq);
- pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).setLoAMachtingMode(
- reqLoAComperison);
+ /**
+ * Extract unique transactionId from AuthnRequest.
+ *
+ * @param el Requested attribute from AuthnRequest
+ * @param pendingReq Current pendingRequest object (has to be of type {@link RequestImpl})
+ * @return <code>true</code> if transactionId extraction was successful, otherwise <code>false</code>
+ */
+ private boolean extractUniqueTransactionId(EaafRequestedAttribute el, IRequest pendingReq) {
+ if (!(pendingReq instanceof RequestImpl)) {
+ log.warn("Can NOT set unique transactionId from AuthnRequest,because 'PendingRequest' is NOT from Type: {}",
+ RequestImpl.class.getName());
+
+ } else {
+ if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) {
+ final String transactionId = el.getAttributeValues().get(0).getDOM().getTextContent();
+ ((RequestImpl)pendingReq).setUniqueTransactionIdentifier(transactionId);
+ return true;
- // validate and process requested attributes
- boolean sectorDetected = false;
+ } else {
+ log.warn("Req. attribute '{}' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute",
+ el.getName());
+
+ }
- if (authnReq.getExtensions() != null) {
- final List<XMLObject> 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()) {
- log.trace("Processing req. attribute '" + el.getName() + "' ... ");
- if (el.getName().equals(PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME)) {
- if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) {
- final String sectorId = el.getAttributeValues().get(0).getDOM().getTextContent();
- final ServiceProviderConfiguration spConfig = pendingReq.getServiceProviderConfiguration(
- ServiceProviderConfiguration.class);
-
- try {
- spConfig.setBpkTargetIdentifier(sectorId);
- sectorDetected = true;
-
- } catch (final EaafException e) {
- log.info("Requested sector: " + sectorId + " DOES NOT match to allowed sectors for SP: "
- + spConfig.getUniqueIdentifier());
- }
-
- } else {
- log.info("Req. attribute '" + el.getName()
- + "' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute");
- }
-
- } else {
- log.debug("Ignore req. attribute: " + el.getName());
- }
-
- }
-
- } else {
- log.debug("No requested Attributes in Authn. Request");
- }
-
- } else {
- log.info("Ignore unknown requested attribute: " + reqAttrObj.getElementQName().toString());
- }
+ }
+
+ return false;
+ }
+
+ /**
+ * Extract the bPK target from requested attribute.
+ *
+ * @param el Requested attribute from AuthnRequest
+ * @param spConfig Service-Provider configuration for current process
+ * @return <code>true</code> if bPK target extraction was successful, otherwise <code>false</code>
+ */
+ private boolean extractBpkTargetIdentifier(EaafRequestedAttribute el, ServiceProviderConfiguration spConfig) {
+ if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) {
+ final String sectorId = el.getAttributeValues().get(0).getDOM().getTextContent();
+ try {
+ spConfig.setBpkTargetIdentifier(sectorId);
+ return true;
+
+ } catch (final EaafException e) {
+ log.warn("Requested sector: " + sectorId + " DOES NOT match to allowed sectors for SP: "
+ + spConfig.getUniqueIdentifier());
+ }
+
+ } else {
+ log.warn("Req. attribute '" + el.getName()
+ + "' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute");
+ }
+
+ return false;
+
+ }
+ private void postprocessLoaLevel(IRequest pendingReq, AuthnRequest authnReq)
+ throws AuthnRequestValidatorException {
+ final List<String> reqLoA = extractLoA(authnReq);
+ log.trace("SP requests LoA with: {}", String.join(", ",reqLoA));
+
+ LevelOfAssurance minimumLoAFromConfig = LevelOfAssurance.fromString(basicConfig.getBasicConfiguration(
+ MsEidasNodeConstants.PROP_EIDAS_REQUEST_LOA_MINIMUM_LEVEL,
+ EaafConstants.EIDAS_LOA_HIGH));
+ if (minimumLoAFromConfig == null) {
+ log.warn("Can not load minimum LoA from configuration. Use LoA: {} as default",
+ EaafConstants.EIDAS_LOA_HIGH);
+ minimumLoAFromConfig = LevelOfAssurance.HIGH;
+
+ }
+
+ log.trace("Validate requested LoA to connector configuration minimum LoA: {} ...",
+ minimumLoAFromConfig);
+ final List<String> allowedLoA = new ArrayList<>();
+ for (final String loa : reqLoA) {
+ try {
+ final LevelOfAssurance intLoa = LevelOfAssurance.fromString(loa);
+ String selectedLoA = EaafConstants.EIDAS_LOA_HIGH;
+ if (intLoa != null
+ && intLoa.numericValue() <= minimumLoAFromConfig.numericValue()) {
+ log.info("Client: {} requested LoA: {} will be upgraded to: {}",
+ pendingReq.getServiceProviderConfiguration().getUniqueIdentifier(),
+ loa,
+ minimumLoAFromConfig);
+ selectedLoA = minimumLoAFromConfig.getValue();
+
}
- }
- if (!sectorDetected) {
- log.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" });
+ if (!allowedLoA.contains(selectedLoA)) {
+ log.debug("Allow LoA: {} for Client: {}",
+ selectedLoA,
+ pendingReq.getServiceProviderConfiguration().getUniqueIdentifier());
+ allowedLoA.add(selectedLoA);
- }
+ }
- } catch (final EaafStorageException e) {
- log.info("Can NOT store Authn. Req. data into pendingRequest.", e);
- throw new AuthnRequestValidatorException("internal.02", null, e);
+ } catch (final IllegalArgumentException e) {
+ log.warn("LoA: {} is currently NOT supported and it will be ignored.", loa);
+
+ }
}
+ pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).setRequiredLoA(
+ allowedLoA);
+
}
private String extractComparisonLevel(AuthnRequest authnReq) {