aboutsummaryrefslogtreecommitdiff
path: root/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java
diff options
context:
space:
mode:
Diffstat (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java')
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java313
1 files changed, 313 insertions, 0 deletions
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java
new file mode 100644
index 00000000..358b681e
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.tasks;
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.SingleSignOnService;
+import org.opensaml.saml2.metadata.provider.MetadataProviderException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import com.google.common.net.MediaType;
+
+import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.Constants;
+import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.frontend.velocity.VelocityProvider;
+import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
+import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
+import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters;
+import at.gv.egovernment.moa.id.commons.api.IRequest;
+import at.gv.egovernment.moa.id.commons.api.data.CPEPS;
+import at.gv.egovernment.moa.id.commons.api.data.StorkAttribute;
+import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException;
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+import eu.eidas.auth.commons.EidasStringUtil;
+import eu.eidas.auth.commons.attribute.AttributeDefinition;
+import eu.eidas.auth.commons.attribute.AttributeDefinition.Builder;
+import eu.eidas.auth.commons.light.impl.LightRequest;
+import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
+import eu.eidas.auth.commons.protocol.IRequestMessage;
+import eu.eidas.auth.commons.protocol.eidas.LevelOfAssurance;
+import eu.eidas.auth.commons.protocol.eidas.LevelOfAssuranceComparison;
+import eu.eidas.auth.commons.protocol.eidas.SpType;
+import eu.eidas.auth.commons.protocol.eidas.impl.EidasAuthenticationRequest;
+
+/**
+ * @author tlenz
+ *
+ */
+@Component("GenerateAuthnRequestTask")
+public class GenerateAuthnRequestTask extends AbstractAuthServletTask {
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public void execute(ExecutionContext executionContext,
+ HttpServletRequest request, HttpServletResponse response)
+ throws TaskExecutionException {
+
+ try{
+ //get service-provider configuration
+ IOAAuthParameters oaConfig = pendingReq.getOnlineApplicationConfiguration();
+
+ // get target and validate citizen countryCode
+ String citizenCountryCode = (String) executionContext.get(MOAIDAuthConstants.PARAM_CCC);
+
+ if (StringUtils.isEmpty(citizenCountryCode)) {
+ // illegal state; task should not have been executed without a selected country
+ throw new AuthenticationException("eIDAS.03", new Object[] { "" });
+
+ }
+ CPEPS cpeps = authConfig.getStorkConfig().getCPEPSWithFullName(citizenCountryCode);
+ if(null == cpeps) {
+ Logger.error("PEPS unknown for country: " + citizenCountryCode);
+ throw new AuthenticationException("eIDAS.04", new Object[] {citizenCountryCode});
+ }
+ Logger.debug("Found eIDaS Node/C-PEPS configuration for citizen of country: " + citizenCountryCode);
+
+
+ //TODO: load authnReq End-Point URL from configuration
+ SingleSignOnService authnReqEndpoint = null;
+
+
+ //TODO: switch to entityID and set new status codes
+// revisionsLogger.logEvent(oaConfig, pendingReq,
+// MOAIDEventConstants.AUTHPROCESS_PEPS_SELECTED,
+// metadataUrl);
+
+ // assemble requested attributes
+ Collection<StorkAttribute> attributesFromConfig = oaConfig.getRequestedSTORKAttributes();
+
+ // - prepare attribute list
+
+ // - fill container
+ List<AttributeDefinition<?>> reqAttrList = new ArrayList<AttributeDefinition<?>>();
+ //TODO: update requested attribute builder
+// for (StorkAttribute current : attributesFromConfig) {
+// AttributeDefinition<?> newAttribute = SAMLEngineUtils.getMapOfAllAvailableAttributes().get(current.getName());
+//
+// if (newAttribute == null) {
+// Logger.warn("eIDAS attribute with friendlyName:" + current.getName() + " is not supported.");
+//
+// } else {
+// boolean globallyMandatory = false;
+// for (StorkAttribute currentGlobalAttribute : authConfig.getStorkConfig().getStorkAttributes())
+// if (current.getName().equals(currentGlobalAttribute.getName())) {
+// globallyMandatory = BooleanUtils.isTrue(currentGlobalAttribute.getMandatory());
+// break;
+// }
+//
+// Builder<?> attrBuilder = AttributeDefinition.builder(newAttribute).required(current.getMandatory() || globallyMandatory);
+// reqAttrList.add(attrBuilder.build());
+//
+// }
+// }
+
+ //request
+// if (reqAttrList.isEmpty()) {
+// Logger.info("No attributes requested by OA:" + pendingReq.getOnlineApplicationConfiguration().getPublicURLPrefix()
+// + " --> Request attr:" + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + " by default");
+// AttributeDefinition<?> newAttribute = SAMLEngineUtils.getMapOfAllAvailableAttributes().get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+// Builder<?> attrBuilder = AttributeDefinition.builder(newAttribute).required(true);
+// reqAttrList.add(attrBuilder.build());
+//
+// }
+
+ //build requested attribute set
+ ImmutableAttributeMap reqAttrMap = new ImmutableAttributeMap.Builder().putAll(reqAttrList).build();
+
+ //build eIDAS AuthnRequest
+ LightRequest.Builder authnRequestBuilder = LightRequest.builder();
+
+ authnRequestBuilder.id(UUID.randomUUID().toString());
+ authnRequestBuilder.providerName(pendingReq.getAuthURL());
+ String issur = pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_METADATA;
+ authnRequestBuilder.issuer(issur);
+
+ //TODO:
+ //authnRequestBuilder.destination(authnReqEndpoint.getLocation());
+
+
+ authnRequestBuilder.nameIdFormat(Constants.eIDAS_REQ_NAMEID_FORMAT);
+
+ //set minimum required eIDAS LoA from OA config
+ String LoA = oaConfig.getQaaLevel();
+ //TODO:
+// if (MiscUtil.isNotEmpty(LoA))
+// authnRequestBuilder.levelOfAssurance(LevelOfAssurance.fromString(oaConfig.getQaaLevel()));
+// else
+ authnRequestBuilder.levelOfAssurance(LevelOfAssurance.HIGH.getValue());
+
+ //TODO: check if required
+ //authnRequestBuilder.levelOfAssuranceComparison(LevelOfAssuranceComparison.MINIMUM);
+
+
+ //set correct SPType for this online application
+ if (oaConfig.hasBaseIdTransferRestriction())
+ authnRequestBuilder.spType(SpType.PRIVATE.getValue());
+ else
+ authnRequestBuilder.spType(SpType.PUBLIC.getValue());
+
+
+ //TODO
+ //set service provider (eIDAS node) countryCode
+// authnRequestBuilder.serviceProviderCountryCode(
+// authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, "AT"));
+
+ //set citizen country code for foreign uses
+ authnRequestBuilder.citizenCountryCode(cpeps.getCountryCode());
+
+ //add requested attributes
+ authnRequestBuilder.requestedAttributes(reqAttrMap);
+
+
+ LightRequest lightAuthnReq = authnRequestBuilder.build();
+
+
+
+ //IRequestMessage authnRequest = engine.generateRequestMessage(authnRequestBuilder.build(), issur);
+
+ //encode AuthnRequest
+// byte[] token = authnRequest.getMessageBytes();
+// String SAMLRequest = EidasStringUtil.encodeToBase64(token);
+
+
+// if (SAMLConstants.SAML2_POST_BINDING_URI.equals(authnReqEndpoint.getBinding()))
+// buildPostBindingRequest(pendingReq, authnReqEndpoint, SAMLRequest, authnRequest, response);
+//
+// //TODO: redirect Binding is not completely implemented
+// //else if (SAMLConstants.SAML2_REDIRECT_BINDING_URI.equals(authnReqEndpoint.getBinding()))
+// //buildRedirecttBindingRequest(pendingReq, authnReqEndpoint, token, authnRequest, response);
+//
+// else {
+// Logger.error("eIDAS-node use an unsupported binding ("
+// + authnReqEndpoint.getBinding() + "). Request eIDAS node not possible.");
+// throw new MOAIDException("eIDAS.02", new Object[]{"eIDAS-node use an unsupported binding"});
+//
+// }
+
+
+
+// }catch (EIDASSAMLEngineException e){
+// throw new TaskExecutionException(pendingReq, "eIDAS AuthnRequest generation FAILED.",
+// new EIDASEngineException("eIDAS.00", new Object[]{e.getMessage()}, e));
+
+ } catch (MOAIDException e) {
+ throw new TaskExecutionException(pendingReq, "eIDAS AuthnRequest generation FAILED.", e);
+
+ } catch (Exception e) {
+ Logger.error("eIDAS AuthnRequest generation FAILED.", e);
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ }
+ }
+
+ /**
+ * Encode the eIDAS request with POST binding
+ *
+ * @param pendingReq
+ * @param authnReqEndpoint
+ * @param SAMLRequest
+ * @param authnRequest
+ * @param response
+ * @throws MOAIDException
+ */
+ private void buildPostBindingRequest(IRequest pendingReq, SingleSignOnService authnReqEndpoint,
+ String SAMLRequest, IRequestMessage authnRequest, HttpServletResponse response)
+ throws MOAIDException {
+ //send
+ try {
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/eidas_postbinding_template.vm");
+ VelocityContext context = new VelocityContext();
+
+ String actionType = "SAMLRequest";
+ context.put(actionType, SAMLRequest);
+ context.put("RelayState", pendingReq.getRequestID());
+ context.put("action", authnReqEndpoint.getLocation());
+
+ Logger.debug("Using SingleSignOnService url as action: " + authnReqEndpoint.getLocation());
+ Logger.debug("Encoded " + actionType + " original: " + SAMLRequest);
+
+ Logger.trace("Starting template merge");
+ StringWriter writer = new StringWriter();
+
+ Logger.trace("Doing template merge");
+ template.merge(context, writer);
+
+ Logger.trace("Template merge done");
+ Logger.trace("Sending html content: " + writer.getBuffer().toString());
+
+
+ byte[] content = writer.getBuffer().toString().getBytes("UTF-8");
+ response.setContentType(MediaType.HTML_UTF_8.toString());
+ response.setContentLength(content.length);
+ response.getOutputStream().write(content);
+
+ revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq,
+ MOAIDEventConstants.AUTHPROCESS_PEPS_REQUESTED,
+ authnRequest.getRequest().getId());
+
+ } catch (Exception e) {
+ Logger.error("Velocity general error: " + e.getMessage());
+ throw new MOAIDException("eIDAS.02", new Object[]{e.getMessage()}, e);
+
+ }
+
+ }
+
+ /**
+ * Select a SingleSignOnService endPoint from eIDAS node metadata.
+ * This endPoint receives the Authn. request
+ *
+ * @param idpEntity
+ * @return
+ */
+ private SingleSignOnService selectSingleSignOnServiceFromMetadata(EntityDescriptor idpEntity) {
+ //select SingleSignOn Service endpoint from IDP metadata
+ SingleSignOnService endpoint = null;
+ if (idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS) == null) {
+ return null;
+
+ }
+
+ for (SingleSignOnService sss :
+ idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS).getSingleSignOnServices()) {
+
+ // use POST binding as default if it exists
+ if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI))
+ endpoint = sss;
+
+ //TODO: redirect Binding is not completely implemented
+ // use Redirect binding as backup
+// else if ( sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)
+// && endpoint == null )
+// endpoint = sss;
+
+ }
+
+ return endpoint;
+ }
+
+}