aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java')
-rw-r--r--id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java367
1 files changed, 0 insertions, 367 deletions
diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java
deleted file mode 100644
index 2e72f216a..000000000
--- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java
+++ /dev/null
@@ -1,367 +0,0 @@
-/*******************************************************************************
- * Copyright 2014 Federal Chancellery Austria
- * MOA-ID has been developed in a cooperation between BRZ, the Federal
- * Chancellery Austria - ICT staff unit, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://www.osor.eu/eupl/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-package at.gv.egovernment.moa.id.protocols.stork2;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
-import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
-import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
-import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
-import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
-import at.gv.egovernment.moa.id.data.IAuthData;
-import at.gv.egovernment.moa.id.data.SLOInformationImpl;
-import at.gv.egovernment.moa.id.data.SLOInformationInterface;
-import at.gv.egovernment.moa.id.moduls.IAction;
-import at.gv.egovernment.moa.id.moduls.IRequest;
-import at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider;
-import at.gv.egovernment.moa.id.storage.AssertionStorage;
-import at.gv.egovernment.moa.logging.Logger;
-import eu.stork.peps.auth.commons.*;
-import eu.stork.peps.auth.engine.STORKSAMLEngine;
-import eu.stork.peps.complex.attributes.eu.stork.names.tc.stork._1_0.assertion.AttributeStatusType;
-import eu.stork.peps.exceptions.STORKSAMLEngineException;
-
-import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * The AttributeCollector Action tries to get all requested attributes from a set of {@link AttributeProvider} Plugins.
- * The class is called whenever the {@link AuthenticationRequest} Action is invoked and checks for missing attributes.
- * Furthermore, the class can handle direct posts. That is when the class triggers an attribute query which needs user
- * interaction, redirect to another portal, etc. The redirect will hit here and the class can continue to fetch attributes.
- *
- * TODO how do we treat mandatory and optional attributes?
- */
-public class AttributeCollector implements IAction {
-
- /**
- * The Constant ARTIFACT_ID.
- */
- private static final String ARTIFACT_ID = "artifactId";
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.moduls.IAction#processRequest(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.auth.data.AuthenticationSession)
- */
- public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException {
-
- // - fetch the container
- String artifactId = (String) httpReq.getParameter(ARTIFACT_ID);
- DataContainer container;
- try {
- container = AssertionStorage.getInstance().get(artifactId, DataContainer.class);
- } catch (MOADatabaseException e) {
- Logger.error("Error fetching incomplete Stork response from temporary storage. Most likely a timeout occured.", e);
- throw new MOAIDException("stork.11", null);
- }
-
-
- if (httpReq.getParameter("SAMLResponse") != null) {
- Logger.info("Got SAML response from external attribute provider.");
-
- MOASTORKResponse STORK2Response = new MOASTORKResponse(httpReq);
-
- //extract STORK Response from HTTP Request
- byte[] decSamlToken;
- try {
- decSamlToken = PEPSUtil.decodeSAMLToken(httpReq.getParameter("SAMLResponse"));
- } catch (NullPointerException e) {
- if (httpReq.getRemoteHost().contains("129.27.142")) {
- Logger.warn("Availability check by " + httpReq.getRemoteHost() + " on URI: " + httpReq.getRequestURI());
- } else {
- Logger.error("Unable to retrieve STORK Request for host: " + httpReq.getRemoteHost() + " and URI: " + httpReq.getRequestURI(), e);
- }
- throw new MOAIDException("stork.04", null);
- }
-
- //Get SAMLEngine instance
- STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
-
- STORKAuthnResponse authnResponse = null;
-
-
- // check if valid authn response is contained
- try {
- authnResponse = engine.validateSTORKAuthnResponse(decSamlToken, httpReq.getRemoteAddr());
- } catch (STORKSAMLEngineException ex) {
- Logger.error("Unable to validate Stork AuthenticationResponse: " + ex.getMessage());
- }
-
- STORK2Response.setSTORKAuthnResponseToken(decSamlToken);
-
- // check if the attributes are provided for the same person from request
- // requires presence of eIdentifier for unambigious correlation
- Logger.debug("Checking if the attribute relates to the correct person..");
- try {
- String remoteEIdentifier= authnResponse.getPersonalAttributeList().get("eIdentifier").getValue().get(0);
- String localEidentifier= container.getResponse().getStorkAuthnResponse().getPersonalAttributeList().get("eIdentifier").getValue().get(0);
- if (!remoteEIdentifier.equals(localEidentifier)) {
- Logger.error("The attribute is not provided for the same person!");
- throw new MOAIDException("stork.25", null);
- }
- } catch (NullPointerException ex) {
- Logger.warn("Could not check the correlation of attributes from external provider. Ignoring the check.");
- //Logger.debug(ex);
- //throw new MOAIDException("stork.04", null); // TODO revise message, raise exception when ehvd checked
- }
-
- if (authnResponse.getPersonalAttributeList().size() > 0) {
- Logger.info("Response from external attribute provider contains " + authnResponse.getPersonalAttributeList().size() + " attributes.");
- container.getResponse().setPersonalAttributeList(addOrUpdateAll(container.getResponse().getPersonalAttributeList(), authnResponse.getPersonalAttributeList()));
- }
-
- }
-
- // end addition
-
-
- // read configuration parameters of OA
- OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(container.getRequest().getAssertionConsumerServiceURL());
- if (oaParam == null)
- throw new AuthenticationException("stork.12", new Object[]{container.getRequest().getAssertionConsumerServiceURL()});
-
- // find the attribute provider plugin that can handle the response
- IPersonalAttributeList newAttributes = null;
-
- Iterator<AttributeProvider> attibuteProvidersInterator = AttributeProviderFactory.getConfiguredPlugins(oaParam.getStorkAPs());
- while(attibuteProvidersInterator.hasNext())
- try {
- newAttributes = attibuteProvidersInterator.next().parse(httpReq);
-
- // stop as soon as we hit a capable plugin
- break;
- } catch (UnsupportedAttributeException e1) {
- // the current provider cannot find anything familiar within the
- // provided httpreq. Try the next one.
- }
-
- if (null == newAttributes) {
- // we do not have a provider which is capable of fetching something
- // from the received httpreq.
- Logger.error("No attribute could be retrieved from the response the attribute provider gave us.");
- }
-
- // - insert the embedded attribute(s) into the container
- if (null != newAttributes)
- container.getResponse().setPersonalAttributeList(addOrUpdateAll(container.getResponse().getPersonalAttributeList(), newAttributes));
-
- // see if we need some more attributes
- SLOInformationImpl sloInfo = (SLOInformationImpl) processRequest(container, httpReq, httpResp, authData, oaParam);
-
- if (sloInfo == null) {
- sloInfo = new SLOInformationImpl(req.getAuthURL(), null, null, null, req.requestedModule());
- }
-
- return sloInfo;
-
- }
-
- /**
- * Checks if there are missing attributes and tries to fetch them. If there are no more attribute to fetch,
- * this very method creates and sends the protocol result to the asking S-PEPS.
- *
- * @param container the {@link DataContainer} representing the status of the overall query.
- * @return the string
- * @throws MOAIDException
- */
- public SLOInformationInterface processRequest(DataContainer container, HttpServletRequest request, HttpServletResponse response, IAuthData authData, OAAuthParameter oaParam) throws MOAIDException {
- // check if there are attributes we need to fetch
-
- IPersonalAttributeList requestAttributeList = container.getRequest().getPersonalAttributeList();
- IPersonalAttributeList responseAttributeList = container.getResponse().getPersonalAttributeList();
- List<PersonalAttribute> missingAttributes = new ArrayList<PersonalAttribute>();
- Logger.debug("aquire list of missing attributes");
- for (PersonalAttribute current : requestAttributeList)
- if (!responseAttributeList.containsKey(current.getName())) {
- if(null == current.getStatus() || (null != current.getStatus() && !current.getStatus().equals(AttributeStatusType.WITHHELD.value()))) {
- // add the ones we need
- missingAttributes.add(current);
- Logger.debug("add " + current.getName() + " to the list of missing attributes");
- }
- } else {
- // remove the ones we do not want to share from the response list
- if(null != current.getStatus() && current.getStatus().equals(AttributeStatusType.WITHHELD.value())) {
- responseAttributeList.remove(current.getName());
- Logger.debug("remove " + current.getName() + " from the list of resulting attributes because the user does not want to disclose the data");
- }
- }
-
- Logger.info("collecting attributes...");
- Logger.debug("found " + missingAttributes.size() + " missing attributes");
-
- // Try to get all missing attributes
- try {
- // for each attribute still missing
- for (PersonalAttribute currentAttribute : missingAttributes) {
-
- /*
- * prefill attributes with "notAvailable". If we get them later, we override the value and status.
- * This way, there is no error case in which an attribute is left unanswered.
- */
- IPersonalAttributeList aquiredAttributes = new PersonalAttributeList();
- currentAttribute.setStatus(AttributeStatusType.NOT_AVAILABLE.value());
- aquiredAttributes.add((PersonalAttribute) currentAttribute.clone());
- container.getResponse().setPersonalAttributeList(
- addOrUpdateAll(container.getResponse().getPersonalAttributeList(), aquiredAttributes));
- // - check if we can find a suitable AttributeProvider Plugin
-
- Iterator<AttributeProvider> attibuteProvidersInterator = AttributeProviderFactory.getConfiguredPlugins(oaParam.getStorkAPs());
- while(attibuteProvidersInterator.hasNext()) {
- AttributeProvider currentProvider = attibuteProvidersInterator.next();
-
- // build a section of attribute provider's predefined attributes and missing attributes
- // only missing attributes that can be handled by attribute provider will be sent to it
- List<PersonalAttribute> currentProviderConfiguredAttributes = new ArrayList<PersonalAttribute>();
- for (String attributeName : currentProvider.getSupportedAttributeNames()) {
- for (PersonalAttribute missingAttribute : missingAttributes) {
- if (missingAttribute.getName().equals(attributeName)) {
- currentProviderConfiguredAttributes.add(missingAttribute);
- break;
- }
- }
- }
-
- try {
- // - hand over control to the suitable plugin
- Logger.info(currentProvider.getClass().getSimpleName() + " called to handle attribute '" + currentAttribute.getName() + "'");
-
- //aquiredAttributes = currentProvider.acquire(currentAttribute, container.getRequest().getSpCountry(), moasession);
- //aquiredAttributes = currentProvider.acquire(missingAttributes, container.getRequest().getSpCountry(), moasession);
- aquiredAttributes = currentProvider.acquire(currentProviderConfiguredAttributes, container.getRequest(), authData);
-
- Logger.info(currentProvider.getClass().getSimpleName() + " can handle attribute '" + currentAttribute.getName() + "'");
- break;
- } catch (UnsupportedAttributeException e) {
- // ok, try the next attributeprovider
- Logger.info(currentProvider.getClass().getSimpleName() + " could not handle attribute '" + currentAttribute.getName() + "'");
- } catch (MOAIDException e) {
- // the current plugin had an error. Try the next one.
- Logger.info(currentProvider.getClass().getSimpleName() + " could not handle attribute '" + currentAttribute.getName() + "' due to an error");
- }
- }
-
- // check if we could fetch the attribute
- if (null == aquiredAttributes) {
- // if not
- Logger.error("We have no suitable plugin for obtaining the attribute '" + currentAttribute.getName() + "'");
- } else
- // else, update any existing attributes
- container.getResponse().setPersonalAttributeList(addOrUpdateAll(container.getResponse().getPersonalAttributeList(), aquiredAttributes));
- }
- Logger.info("collecting attributes done");
-
- // ask for consent if necessary
- new ConsentEvaluator().generateSTORKResponse(response, container);
-
- return null; // AssertionId
- // TODO
-
- } catch (ExternalAttributeRequestRequiredException e) {
- // the attribute request is ongoing and requires an external service.
- try {
- // memorize the container again
- Logger.debug("prepare putting the container into temporary storage...");
-
- // - generate new key
- String newArtifactId = new SecureRandomIdentifierGenerator()
- .generateIdentifier();
- // - put container in temporary store.
- AssertionStorage.getInstance().put(newArtifactId, container);
-
- Logger.debug("...successful");
-
- Logger.info(e.getAp().getClass().getSimpleName() + " is going to ask an external service provider for the requested attributes");
-
- // add container-key to redirect embedded within the return URL
- e.getAp().performRedirect(AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix().get(0) + "/stork2/ResumeAuthentication?" + ARTIFACT_ID + "=" + newArtifactId, request, response, oaParam);
-
- } catch (Exception e1) {
- // TODO should we return the response as is to the PEPS?
- Logger.error("Error putting incomplete Stork response into temporary storage", e1);
- e1.printStackTrace();
- throw new MOAIDException("stork.11", null);
- }
-
- //TODO: in case of Single LogOut -> SLO information has to be stored
- return null; // TODO what to do here?
- }
- }
-
- /**
- * Adds or updates all {@link PersonalAttribute} objects given in {@code source} to/in {@code target}.
- *
- * @param target the target
- * @param source the source
- * @return
- * @throws MOAIDException
- */
- private PersonalAttributeList addOrUpdateAll(IPersonalAttributeList target, IPersonalAttributeList source) throws MOAIDException {
-
- PersonalAttributeList updatedList = new PersonalAttributeList();
- for (PersonalAttribute el : target)
- updatedList.add(el);
-
- Logger.debug("Updating " + source.size() + " attributes...");
- for (PersonalAttribute current : source) {
- Logger.debug("treating " + current.getName());
-
- // check if we need to update the current pa
- if (updatedList.containsKey(current.getName())) {
- PersonalAttribute existing = target.get(current.getName());
- if(!(existing.isEmptyValue() && existing.isEmptyComplexValue()))
- if(!(existing.getValue().equals(current.getValue()) || existing.getComplexValue().equals(current.getComplexValue()))) {
- Logger.error("Attribute Value does not match the value from first authentication!");
- throw new MOAIDException("stork.16", new Object[] {existing.getName()});
- }
-
- updatedList.get(current.getName()).setStatus(current.getStatus());
- updatedList.get(current.getName()).setValue(current.getValue());
- updatedList.get(current.getName()).setComplexValue(current.getComplexValue());
- } else
- updatedList.add(current);
-
- Logger.debug("...successfully treated " + current.getName());
- }
-
- return updatedList;
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.moduls.IAction#needAuthentication(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
- */
- public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) {
- // this action does not need any authentication. The authentication is already done by the preceding AuthenticationRequest-Action.
- return false;
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName()
- */
- public String getDefaultActionName() {
- return STORKProtocol.ATTRIBUTE_COLLECTOR;
- }
-}