From 07318e70ea3a9d25ca945c391820149183c61ca0 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Mon, 8 Feb 2021 18:47:34 +0100 Subject: add Binding Public-Key into technical AuthBlock in case of an ID Austria process --- .../verification/AuthnRequestValidator.java | 114 +++++++++++++-------- 1 file changed, 69 insertions(+), 45 deletions(-) (limited to 'connector/src/main') 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 a9eb06be..881eeb8a 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 @@ -75,7 +75,7 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor { if (nameIdPolicy != null) { final String nameIdFormat = nameIdPolicy.getFormat(); if (nameIdFormat != null) { - if (!(NameIDType.TRANSIENT.equals(nameIdFormat) + if (!(NameIDType.TRANSIENT.equals(nameIdFormat) || NameIDType.PERSISTENT.equals(nameIdFormat))) { throw new NameIdFormatNotSupportedException(nameIdFormat); @@ -114,10 +114,10 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor { // post-process requested LoA comparison-level pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).setLoAMachtingMode( extractComparisonLevel(authnReq)); - - //extract information from requested attributes + + // extract information from requested attributes extractFromRequestedAttriutes(pendingReq, authnReq); - + } catch (final EaafStorageException e) { log.info("Can NOT store Authn. Req. data into pendingRequest.", e); throw new AuthnRequestValidatorException("internal.02", null, e); @@ -126,14 +126,14 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor { } - private void extractFromRequestedAttriutes(IRequest pendingReq, AuthnRequest authnReq) - throws AuthnRequestValidatorException { + private void extractFromRequestedAttriutes(IRequest pendingReq, AuthnRequest authnReq) + throws AuthnRequestValidatorException, EaafStorageException { // validate and process requested attributes boolean sectorDetected = false; - + final ServiceProviderConfiguration spConfig = pendingReq.getServiceProviderConfiguration( ServiceProviderConfiguration.class); - + if (authnReq.getExtensions() != null) { final List requestedAttributes = authnReq.getExtensions().getUnknownXMLObjects(); for (final XMLObject reqAttrObj : requestedAttributes) { @@ -143,77 +143,101 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor { 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); - + sectorDetected = extractBpkTargetIdentifier(el, spConfig); + } else if (el.getName().equals(ExtendedPvpAttributeDefinitions.EID_TRANSACTION_ID_NAME)) { extractUniqueTransactionId(el, pendingReq); - + + } else if (el.getName().equals(MsEidasNodeConstants.EID_BINDING_PUBLIC_KEY_NAME)) { + extractBindingPublicKey(el, pendingReq); + } 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()); - + } } } - + 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" }); } - + + } + + private void extractBindingPublicKey(EaafRequestedAttribute el, IRequest pendingReq) + throws EaafStorageException { + if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) { + final String bindingPubKey = el.getAttributeValues().get(0).getDOM().getTextContent(); + pendingReq.setRawDataToTransaction(MsEidasNodeConstants.EID_BINDING_PUBLIC_KEY_NAME, bindingPubKey); + log.info("Find Binding Public-Key. eIDAS authentication will be used to create an ID Austria Binding"); + + } else { + log.warn( + "Req. attribute '{}' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute", + el.getName()); + + } } /** * Extract unique transactionId from AuthnRequest. - * - * @param el Requested attribute from AuthnRequest - * @param pendingReq Current pendingRequest object (has to be of type {@link RequestImpl}) - * @return true if transactionId extraction was successful, otherwise false + * + * @param el Requested attribute from AuthnRequest + * @param pendingReq Current pendingRequest object (has to be of type + * {@link RequestImpl}) + * @return true if transactionId extraction was successful, + * otherwise false */ 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: {}", + log.warn( + "Can NOT set unique transactionId from AuthnRequest,because 'PendingRequest' is NOT from Type: {}", RequestImpl.class.getName()); - - } else { + + } else { if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) { - final String transactionId = el.getAttributeValues().get(0).getDOM().getTextContent(); - ((RequestImpl)pendingReq).setUniqueTransactionIdentifier(transactionId); + final String transactionId = el.getAttributeValues().get(0).getDOM().getTextContent(); + ((RequestImpl) pendingReq).setUniqueTransactionIdentifier(transactionId); return true; } else { - log.warn("Req. attribute '{}' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute", + log.warn( + "Req. attribute '{}' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute", el.getName()); - + } - + } - + return false; } /** * Extract the bPK target from requested attribute. - * - * @param el Requested attribute from AuthnRequest + * + * @param el Requested attribute from AuthnRequest * @param spConfig Service-Provider configuration for current process - * @return true if bPK target extraction was successful, otherwise false + * @return true if bPK target extraction was successful, otherwise + * false */ - private boolean extractBpkTargetIdentifier(EaafRequestedAttribute el, ServiceProviderConfiguration spConfig) { + private boolean extractBpkTargetIdentifier(EaafRequestedAttribute el, + ServiceProviderConfiguration spConfig) { if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) { - final String sectorId = el.getAttributeValues().get(0).getDOM().getTextContent(); + final String sectorId = el.getAttributeValues().get(0).getDOM().getTextContent(); try { spConfig.setBpkTargetIdentifier(sectorId); return true; @@ -227,16 +251,16 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor { 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) + + private void postprocessLoaLevel(IRequest pendingReq, AuthnRequest authnReq) throws AuthnRequestValidatorException { final List reqLoA = extractLoA(authnReq); - log.trace("SP requests LoA with: {}", String.join(", ",reqLoA)); - + 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)); @@ -246,15 +270,15 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor { minimumLoAFromConfig = LevelOfAssurance.HIGH; } - + log.trace("Validate requested LoA to connector configuration minimum LoA: {} ...", - minimumLoAFromConfig); + minimumLoAFromConfig); final List allowedLoA = new ArrayList<>(); for (final String loa : reqLoA) { try { final LevelOfAssurance intLoa = LevelOfAssurance.fromString(loa); String selectedLoA = EaafConstants.EIDAS_LOA_HIGH; - if (intLoa != null + if (intLoa != null && intLoa.numericValue() <= minimumLoAFromConfig.numericValue()) { log.info("Client: {} requested LoA: {} will be upgraded to: {}", pendingReq.getServiceProviderConfiguration().getUniqueIdentifier(), @@ -281,7 +305,7 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor { pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).setRequiredLoA( allowedLoA); - + } private String extractComparisonLevel(AuthnRequest authnReq) { @@ -335,7 +359,7 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor { private String extractScopeRequsterId(AuthnRequest authnReq) { if (authnReq.getScoping() != null) { final Scoping scoping = authnReq.getScoping(); - if (scoping.getRequesterIDs() != null + if (scoping.getRequesterIDs() != null && scoping.getRequesterIDs().size() > 0) { if (scoping.getRequesterIDs().size() == 1) { return scoping.getRequesterIDs().get(0).getRequesterID(); -- cgit v1.2.3 From c5c6344931f67ccaba335ffa476b5e8117948020 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Wed, 10 Mar 2021 12:25:10 +0100 Subject: switch to EAAF-components 1.1.13-SNAPSHOT to add EID-IDENTITY-STATUS-LEVEL attribute into SAML2 response --- .../builder/AuthenticationDataBuilder.java | 26 +++++++++++++++------- .../src/main/resources/application.properties | 2 ++ .../resources/specific_eIDAS_connector.beans.xml | 6 +++++ 3 files changed, 26 insertions(+), 8 deletions(-) (limited to 'connector/src/main') diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java index c41660ce..3a93c1b8 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/builder/AuthenticationDataBuilder.java @@ -30,6 +30,7 @@ import org.springframework.stereotype.Service; import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions; +import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions.EidIdentityStatusLevelValues; 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.auth.data.IAuthProcessDataContainer; @@ -37,8 +38,9 @@ import at.gv.egiz.eaaf.core.exceptions.EaafBuilderException; import at.gv.egiz.eaaf.core.exceptions.EaafException; import at.gv.egiz.eaaf.core.impl.data.Pair; import at.gv.egiz.eaaf.core.impl.idp.AuthenticationData; +import at.gv.egiz.eaaf.core.impl.idp.EidAuthenticationData; import at.gv.egiz.eaaf.core.impl.idp.auth.builder.AbstractAuthenticationDataBuilder; -import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper; +import at.gv.egiz.eaaf.core.impl.idp.auth.data.EidAuthProcessDataWrapper; import lombok.extern.slf4j.Slf4j; @Service("AuthenticationDataBuilder") @@ -47,9 +49,9 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder @Override protected IAuthData buildDeprecatedAuthData(IRequest pendingReq) throws EaafException { - final IAuthProcessDataContainer authProcessData = - pendingReq.getSessionData(AuthProcessDataWrapper.class); - AuthenticationData authData = new AuthenticationData(); + final EidAuthProcessDataWrapper authProcessData = + pendingReq.getSessionData(EidAuthProcessDataWrapper.class); + EidAuthenticationData authData = new EidAuthenticationData(); //set basis infos super.generateDeprecatedBasicAuthData(authData, pendingReq, authProcessData); @@ -58,6 +60,9 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder authData.setSsoSessionValidTo( new Date(new Date().getTime() + MsEidasNodeConstants.DEFAULT_PVP_ASSERTION_VALIDITY * 60 * 1000)); + authData.setEidStatus(authProcessData.isTestIdentity() + ? EidIdentityStatusLevelValues.TESTIDENTITY : EidIdentityStatusLevelValues.IDENTITY); + return authData; } @@ -65,16 +70,21 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder @Override protected void buildServiceSpecificAuthenticationData(IAuthData authData, IRequest pendingReq) throws EaafException { - if (authData instanceof AuthenticationData) { - ((AuthenticationData)authData).setGenericData( + if (authData instanceof EidAuthenticationData) { + ((EidAuthenticationData)authData).setGenericData( ExtendedPvpAttributeDefinitions.EID_PII_TRANSACTION_ID_NAME, pendingReq.getUniquePiiTransactionIdentifier()); log.trace("Inject piiTransactionId: {} into AuthData", pendingReq.getUniquePiiTransactionIdentifier()); // set specific informations - ((AuthenticationData)authData).setSsoSessionValidTo( + ((EidAuthenticationData)authData).setSsoSessionValidTo( new Date(new Date().getTime() + MsEidasNodeConstants.DEFAULT_PVP_ASSERTION_VALIDITY * 60 * 1000)); + //set E-ID status-level + final EidAuthProcessDataWrapper authProcessData = + pendingReq.getSessionData(EidAuthProcessDataWrapper.class); + ((EidAuthenticationData)authData).setEidStatus(authProcessData.isTestIdentity() + ? EidIdentityStatusLevelValues.TESTIDENTITY : EidIdentityStatusLevelValues.IDENTITY); } else { throw new RuntimeException("Can not inject PiiTransactionId because AuthData is of unknown type: " @@ -86,7 +96,7 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder @Override protected IAuthData getAuthDataInstance(IRequest arg0) throws EaafException { - return new AuthenticationData(); + return new EidAuthenticationData(); } diff --git a/connector/src/main/resources/application.properties b/connector/src/main/resources/application.properties index 9a4ae54f..2411fde3 100644 --- a/connector/src/main/resources/application.properties +++ b/connector/src/main/resources/application.properties @@ -48,6 +48,8 @@ eidas.ms.core.pendingrequestid.digist.algorithm=HmacSHA256 ## eIDAS Ref. Implementation connector ### eidas.ms.auth.eIDAS.node_v2.entityId=ownSpecificConnector +eidas.ms.auth.eIDAS.eid.testidentity.default=false + #eidas.ms.auth.eIDAS.node_v2.forward.endpoint= eidas.ms.auth.eIDAS.node_v2.forward.method=POST eidas.ms.auth.eIDAS.node_v2.countrycode=AT diff --git a/connector/src/main/resources/specific_eIDAS_connector.beans.xml b/connector/src/main/resources/specific_eIDAS_connector.beans.xml index f6fdeefe..0f8511d5 100644 --- a/connector/src/main/resources/specific_eIDAS_connector.beans.xml +++ b/connector/src/main/resources/specific_eIDAS_connector.beans.xml @@ -49,6 +49,9 @@ + + + + + +