diff options
| author | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2020-11-27 09:08:10 +0100 | 
|---|---|---|
| committer | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2020-11-27 09:08:10 +0100 | 
| commit | 7a62a84f23b3a1a1027ebda31fb790ee072793cc (patch) | |
| tree | 7cf1804c99a2876abc934443a2cbfd8d4f59e99b /connector/src/main/java | |
| parent | d01abea064f33d1c985464aadf3e2326c6ba3219 (diff) | |
| download | National_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')
| -rw-r--r-- | connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java | 247 | 
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) { | 
