aboutsummaryrefslogtreecommitdiff
path: root/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java
diff options
context:
space:
mode:
Diffstat (limited to 'modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java')
-rw-r--r--modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java211
1 files changed, 211 insertions, 0 deletions
diff --git a/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java
new file mode 100644
index 00000000..bbe9b45f
--- /dev/null
+++ b/modules/authmodule_id-austria/src/main/java/at/asitplus/eidas/specific/modules/auth/idaustria/tasks/RequestIdAustriaSystemTask.java
@@ -0,0 +1,211 @@
+package at.asitplus.eidas.specific.modules.auth.idaustria.tasks;
+
+import java.security.NoSuchAlgorithmException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.opensaml.messaging.encoder.MessageEncodingException;
+import org.opensaml.saml.saml2.core.Attribute;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;
+import at.asitplus.eidas.specific.modules.auth.idaustria.IdAustriaAuthConstants;
+import at.asitplus.eidas.specific.modules.auth.idaustria.config.IdAustriaAuthRequestBuilderConfiguration;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthCredentialProvider;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.IdAustriaAuthMetadataProvider;
+import at.asitplus.eidas.specific.modules.auth.idaustria.utils.Utils;
+import at.asitplus.eidas.specific.modules.msproxyservice.protocol.ProxyServicePendingRequest;
+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;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
+import at.gv.egiz.eaaf.core.impl.utils.Random;
+import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpAttributeBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AuthnRequestBuildException;
+import at.gv.egiz.eaaf.modules.pvp2.sp.impl.PvpAuthnRequestBuilder;
+import lombok.extern.slf4j.Slf4j;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+import net.shibboleth.utilities.java.support.security.impl.SecureRandomIdentifierGenerationStrategy;
+
+/**
+ * eIDAS Authentication task that generates PVP2 S-Profile request to central
+ * Austrian MS-Connector.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class RequestIdAustriaSystemTask extends AbstractAuthServletTask {
+
+ private static final String ERROR_PVP_02 = "sp.pvp2.02";
+ private static final String ERROR_PVP_13 = "sp.pvp2.13";
+
+ private static final String ERROR_MSG_1 =
+ "Requested 'ms-specific eIDAS node' {0} has no valid metadata or metadata is not found";
+ private static final String ERROR_MSG_4 =
+ "Build PVP2.1 AuthnRequest to connect 'ms-specific eIDAS node' FAILED.";
+
+ @Autowired PvpAuthnRequestBuilder authnReqBuilder;
+ @Autowired IdAustriaAuthCredentialProvider credential;
+ @Autowired IdAustriaAuthMetadataProvider metadataService;
+ @Autowired ITransactionStorage transactionStorage;
+
+ @Override
+ public void execute(ExecutionContext executionContext, HttpServletRequest request,
+ HttpServletResponse response)
+ throws TaskExecutionException {
+ try {
+ //revisionsLogger.logEvent(pendingReq, EidasAuthEventConstants.AUTHPROCESS_EIDAS_AT_CONNECTOR_SELECTED);
+
+ // get entityID for central ID Austria system
+ final String idAustriaEntityID =
+ Utils.getIdAustriaEntityId(pendingReq.getServiceProviderConfiguration(), authConfig);
+ if (StringUtils.isEmpty(idAustriaEntityID)) {
+ log.info("ID Austria authentication not possible -> NO EntityID for central central ID Austria System FOUND!");
+ throw new EaafConfigurationException(IdAustriaAuthConstants.ERRORTYPE_00,
+ new Object[] { IdAustriaAuthConstants.CONFIG_PROPS_IDAUSTRIA_ENTITYID });
+
+ }
+
+ // load IDP SAML2 entitydescriptor
+ final EntityDescriptor entityDesc = metadataService.getEntityDescriptor(idAustriaEntityID);
+ if (entityDesc == null) {
+ throw new EaafConfigurationException(IdAustriaAuthConstants.ERRORTYPE_05,
+ new Object[] { MessageFormat.format(ERROR_MSG_1, idAustriaEntityID) });
+
+ }
+
+ // setup AuthnRequestBuilder configuration
+ final IdAustriaAuthRequestBuilderConfiguration authnReqConfig =
+ new IdAustriaAuthRequestBuilderConfiguration();
+ final SecureRandomIdentifierGenerationStrategy gen =
+ new SecureRandomIdentifierGenerationStrategy();
+
+ // set basic infos
+ authnReqConfig.setRequestId(gen.generateIdentifier());
+ authnReqConfig.setIdpEntity(entityDesc);
+ authnReqConfig.setPassive(false);
+ authnReqConfig.setSignCred(credential.getMessageSigningCredential());
+ authnReqConfig.setSpEntityID(pendingReq.getAuthUrl() + IdAustriaAuthConstants.ENDPOINT_METADATA);
+
+ // set eIDAS Proxy-Service specific information for ID Austria system
+ authnReqConfig.setRequestedAttributes(buildRequestedAttributes(pendingReq));
+
+
+ /*build relayState for session synchronization, because SAML2 only allows RelayState with 80 characters
+ * but encrypted PendingRequestId is much longer.
+ */
+ String relayState = Random.nextProcessReferenceValue();
+ transactionStorage.put(relayState, pendingReq.getPendingRequestId(), -1);
+
+ // build and transmit AuthnRequest
+ authnReqBuilder.buildAuthnRequest(pendingReq, authnReqConfig, relayState, response);
+
+ //revisionsLogger.logEvent(pendingReq,
+ // EidasAuthEventConstants.AUTHPROCESS_EIDAS_AT_CONNECTOR_REQUESTED,
+ // authnReqConfig.getRequestID());
+
+ } catch (final EaafException e) {
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ } catch (final ResolverException e) {
+ throw new TaskExecutionException(pendingReq,
+ ERROR_MSG_4,
+ new AuthnRequestBuildException(ERROR_PVP_02,
+ new Object[] { IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING }, e));
+
+ } catch (MessageEncodingException | NoSuchAlgorithmException | SecurityException e) {
+ throw new TaskExecutionException(pendingReq,
+ e.getMessage(),
+ new AuthnRequestBuildException(ERROR_PVP_13,
+ new Object[] { IdAustriaAuthConstants.MODULE_NAME_FOR_LOGGING }, e));
+
+ } catch (final Exception e) {
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ }
+ }
+
+ private String selectHighestLoa(List<String> requiredLoA) {
+ //TODO: implement LoA selection
+ return requiredLoA.get(0);
+
+ }
+
+ private List<EaafRequestedAttribute> buildRequestedAttributes(IRequest pendingReq) {
+ final List<EaafRequestedAttribute> attributs = new ArrayList<>();
+
+ //build attribute that contains the unique identifier of the eIDAS-Connector
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.EIDAS_CONNECTOR_UNIQUEID_NAME,
+ pendingReq.getServiceProviderConfiguration().getUniqueIdentifier());
+
+ // build EID sector for identification attribute
+ injectAttribute(attributs, PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME,
+ pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier());
+
+ // set requested LoA as attribute
+ injectAttribute(attributs, PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME,
+ selectHighestLoa(pendingReq.getServiceProviderConfiguration().getRequiredLoA()));
+
+ // set list of IDA attributes as attribute
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.SP_REQUIRED_ATTRIBUTES_NAME,
+ StringUtils.join(
+ pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).getRequestedAttributes(),
+ ","));
+
+ //set ProviderName if available
+ String providerName = ((ProxyServicePendingRequest)pendingReq).getEidasRequest().getProviderName();
+ if (StringUtils.isNotEmpty(providerName)) {
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.SP_FRIENDLYNAME_NAME, providerName);
+
+ }
+
+ //set ProviderName if available
+ String requesterId = ((ProxyServicePendingRequest)pendingReq).getEidasRequest().getRequesterId();
+ if (StringUtils.isNotEmpty(requesterId)) {
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.SP_UNIQUEID_NAME, requesterId);
+
+ }
+
+ //set mandate profiles
+ List<String> mandateProfiles =
+ pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).getMandateProfiles();
+ if (mandateProfiles != null && !mandateProfiles.isEmpty()) {
+ log.debug("Set mandate-profiles attribute into ID-Austria request");
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.SP_USED_MANDATE_PROFILES_NAME,
+ StringUtils.join(mandateProfiles, ","));
+
+ }
+
+ // inject mandate mode attribute
+ injectAttribute(attributs, ExtendedPvpAttributeDefinitions.SP_USED_MANDATE_TYPE_NAME,
+ pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).getMandateMode().getMode());
+
+
+ return attributs;
+ }
+
+ private void injectAttribute(List<EaafRequestedAttribute> attributs, String attributeName, String attributeValue) {
+ final Attribute requesterIdAttr = PvpAttributeBuilder.buildEmptyAttribute(attributeName);
+ final EaafRequestedAttribute requesterIdReqAttr = Saml2Utils.generateReqAuthnAttributeSimple(
+ requesterIdAttr,
+ true,
+ attributeValue);
+ attributs.add(requesterIdReqAttr);
+
+ }
+
+}