aboutsummaryrefslogtreecommitdiff
path: root/id/server
diff options
context:
space:
mode:
Diffstat (limited to 'id/server')
-rw-r--r--id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml4
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java5
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java31
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java196
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProvider.java52
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProviderFactory.java57
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java30
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DataContainer.java79
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoNoRedirectAttributeProvider.java48
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoRedirectAttributeProvider.java48
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ExternalAttributeRequestRequiredException.java14
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java2
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/StorkAttributeRequestProvider.java147
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/UnsupportedAttributeException.java7
-rw-r--r--id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties2
-rw-r--r--id/server/moa-id-commons/src/main/resources/config/moaid_config_2.0.xsd13
16 files changed, 721 insertions, 14 deletions
diff --git a/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml b/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml
index b63d413d0..59d6d6cce 100644
--- a/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml
+++ b/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml
@@ -57,6 +57,10 @@
<to type="forward">/dispatcher?mod=id_stork2&amp;action=AuthenticationRequest&amp;%{query-string}</to>
</rule>
<rule match-type="regex">
+ <from>^/stork2/ResumeAuthentication$</from>
+ <to type="forward">/dispatcher?mod=id_stork2&amp;action=AttributeCollector&amp;%{query-string}</to>
+ </rule>
+ <rule match-type="regex">
<from>^/stork2/SendPEPSAuthnRequest$</from>
<to type="forward">/dispatcher?mod=id_stork2&amp;action=AuthenticationRequest&amp;%{query-string}</to>
</rule>
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java
index 8e7ca0779..d1de20c4d 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java
@@ -51,6 +51,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import at.gv.egovernment.moa.id.commons.db.dao.config.AttributeProviderPlugin;
import at.gv.egovernment.moa.id.commons.db.dao.config.AuthComponentOA;
import at.gv.egovernment.moa.id.commons.db.dao.config.BKUSelectionCustomizationType;
import at.gv.egovernment.moa.id.commons.db.dao.config.BKUURLS;
@@ -66,6 +67,7 @@ import at.gv.egovernment.moa.id.commons.db.dao.config.TemplatesType;
import at.gv.egovernment.moa.id.commons.db.dao.config.TransformsInfoType;
import at.gv.egovernment.moa.id.config.ConfigurationUtils;
import at.gv.egovernment.moa.id.config.OAParameter;
+import at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider;
import at.gv.egovernment.moa.id.util.FormBuildUtils;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.MiscUtil;
@@ -348,6 +350,9 @@ public List<OAStorkAttribute> getRequestedAttributes() {
return oa_auth.getOASTORK().getOAAttributes();
}
+public List<AttributeProviderPlugin> getStorkAPs() {
+ return oa_auth.getOASTORK().getAttributeProviders();
+}
public byte[] getBKUSelectionTemplate() {
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java
index f79fd6e17..4dec2c32e 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java
@@ -25,6 +25,7 @@
*/
package at.gv.egovernment.moa.id.config.stork;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
@@ -33,10 +34,15 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
+import at.gv.egovernment.moa.id.commons.db.dao.config.SAMLSigningParameter;
import at.gv.egovernment.moa.id.commons.db.dao.config.STORK;
import at.gv.egovernment.moa.id.commons.db.dao.config.StorkAttribute;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.StringUtils;
+import org.opensaml.ws.message.encoder.MessageEncodingException;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.ParserConfigurationException;
/**
* Encapsulates several STORK configuration parameters according MOA configuration
@@ -59,7 +65,8 @@ public class STORKConfig {
this.props = props;
//create CPEPS map
- List<at.gv.egovernment.moa.id.commons.db.dao.config.CPEPS> cpeps = null;
+ //List<at.gv.egovernment.moa.id.commons.db.dao.config.CPEPS> cpeps = stork.getCPEPS();
+ List<at.gv.egovernment.moa.id.commons.db.dao.config.CPEPS> cpeps = new ArrayList<at.gv.egovernment.moa.id.commons.db.dao.config.CPEPS>(); // TODO Change this
try {
cpeps = stork.getCPEPS();
@@ -82,20 +89,26 @@ public class STORKConfig {
+ cpep.getCountryCode() + " has an invalid URL and is ignored.");
}
}
+ /*catch (ParserConfigurationException e) {
+ Logger.warn("Error in MOA-ID Configuration. CPEP entry for country "
+ + cpep.getCountryCode() + " has an invalid Attribute and is ignored.");
+ } catch (SAXException e) {
+ Logger.warn("Error in MOA-ID Configuration. CPEP entry for country "
+ + cpep.getCountryCode() + " has an invalid Attribute and is ignored.");
+ } catch (IOException e) {
+ Logger.warn("Error in MOA-ID Configuration. CPEP entry for country "
+ + cpep.getCountryCode() + " has an invalid Attribute and is ignored.");
+ } catch (MessageEncodingException e) {
+ Logger.warn("Error in MOA-ID Configuration. CPEP entry for country "
+ + cpep.getCountryCode() + " has an invalid Attribute and is ignored.");
+ }*/
}
-
attr = new ArrayList<StorkAttribute>();
-
- try {
- if (stork.getAttributes() != null) {
+ if (stork.getAttributes() != null) {
for(StorkAttribute current : stork.getAttributes()) {
attr.add(current);
}
}
- } catch (NullPointerException ex) {
- Logger.error("Attributes not configured!");
-
- }
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java
new file mode 100644
index 000000000..08244ab38
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java
@@ -0,0 +1,196 @@
+package at.gv.egovernment.moa.id.protocols.stork2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+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.AuthConfigurationProvider;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.moduls.IAction;
+import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.storage.AssertionStorage;
+import at.gv.egovernment.moa.logging.Logger;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
+
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+
+/**
+ * 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 String processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, AuthenticationSession moasession) throws MOAIDException {
+
+ // read configuration parameters of OA
+ OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(moasession.getPublicOAURLPrefix());
+ if (oaParam == null)
+ throw new AuthenticationException("stork.12", new Object[] { moasession.getPublicOAURLPrefix() });
+
+ // find the attribute provider plugin that can handle the response
+ IPersonalAttributeList newAttributes = null;
+ for (AttributeProvider current : AttributeProviderFactory.getConfiguredPlugins(oaParam.getStorkAPs()))
+ try {
+ newAttributes = current.parse(httpReq);
+ } 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.
+ // TODO should we continue with the next attribute?
+ Logger.error("No attribute could be retrieved from the response the attribute provider gave us.");
+ throw new MOAIDException("stork.11", null);
+ }
+
+ // - fetch the container
+ String artifactId = (String) httpReq.getAttribute(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);
+ }
+
+ // - insert the embedded attribute(s) into the container
+ for(PersonalAttribute current : newAttributes)
+ container.getResponse().getPersonalAttributeList().add(current);
+
+ // see if we need some more attributes
+ return processRequest(container, httpReq, httpResp, oaParam);
+ }
+
+ /**
+ * 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 String processRequest(DataContainer container, HttpServletRequest request, HttpServletResponse response, 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>();
+ for(PersonalAttribute current : requestAttributeList)
+ if(!responseAttributeList.containsKey(current))
+ missingAttributes.add(current);
+
+ try {
+ // for each attribute still missing
+ for(PersonalAttribute currentAttribute : missingAttributes) {
+ // - check if we can find a suitable AttributeProvider Plugin
+ for (AttributeProvider currentProvider : AttributeProviderFactory.getConfiguredPlugins(oaParam.getStorkAPs())) {
+ try {
+ // - hand over control to the suitable plugin
+ IPersonalAttributeList aquiredAttributes = currentProvider.acquire(currentAttribute);
+
+ // - add the aquired attribute to the container
+ for(PersonalAttribute current : aquiredAttributes)
+ container.getResponse().getPersonalAttributeList().add(current);
+ } catch(UnsupportedAttributeException e) {
+ // ok, try the next attributeprovider
+ }
+
+ }
+ }
+ } catch (ExternalAttributeRequestRequiredException e) {
+ // the attribute request is ongoing and requires an external service.
+ try {
+ // memorize the container again
+ // - generate new key
+ String newArtifactId = new SecureRandomIdentifierGenerator()
+ .generateIdentifier(); /*
+ Logger.debug("STORK QAA 2 :" + ((STORKAuthnRequestDEL) req).getStorkAuthnRequest().getQAALevel());
+ StartAuthResponse startAuthResponse = getStartAuthResponse(((STORKAuthnRequestDEL) req).getStorkAuthnRequest());
+
+ HttpSession httpSession = httpReq.getSession();
+ httpSession.setAttribute("STORKSessionID", "12345");
+ httpResp.setStatus(startAuthResponse.getHttpStatusCode());
+ try {
+ ServletOutputStream os = httpResp.getOutputStream();
+ String html = new String(startAuthResponse.getContent());
+
+
+ if (html.contains("<![CDATA[")) {
+ Logger.info("-------- content contains <![CDATA[-----------------");
+ Logger.info("-------- content contains html -----------------");
+ Logger.info("HTML : " + html);
+ int beginIndex = html.indexOf("<![CDATA[");
+ int endIndex = html.indexOf("]]>");
+ html = html.substring(beginIndex + 9, endIndex);
+ startAuthResponse.setContent(html.getBytes());
+ }
+ Logger.info("HTML : " + html);
+
+ os.write(startAuthResponse.getContent());
+ Logger.info("Response sent to client");
+ } catch (IOException e) {
+ Logger.error("ERROR MOA");
+ throw new MOAIDException("error response sending", new Object[]{});
+ }
+ //httpSession.setAttribute("CCC", ccc);
+
+ */
+ }
+
+
+ //httpResp.setStatus(200);
+ //VPEPSInboundPostHandler
+
+ // - put container in temporary store.
+ AssertionStorage.getInstance().put(newArtifactId, container);
+
+ // add container-key to redirect embedded within the return URL
+ e.getAp().performRedirect(AuthConfigurationProvider.getInstance().getPublicURLPrefix() + "?" + ARTIFACT_ID + "=" + newArtifactId, container.getRequest().getCitizenCountryCode(), 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", e);
+ throw new MOAIDException("stork.11", null);
+ }
+
+ return "12345"; // TODO what to do here?
+ }
+ // build response
+ // done
+ return "12345"; // AssertionId
+ }
+
+ /* (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;
+ }
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProvider.java
new file mode 100644
index 000000000..adf57d77b
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProvider.java
@@ -0,0 +1,52 @@
+package at.gv.egovernment.moa.id.protocols.stork2;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+
+/**
+ * An {@link AttributeProvider} can fetch a set of stork attributes. It might complete the query within one method call,
+ * but might also need to redirect to another webservice to accomplish its task.
+ */
+public interface AttributeProvider {
+
+ /**
+ * Acquire the specified attribute. Returns {@code null} when attribute retrieval is in progress, but requires for
+ * for redirecting the user to an external service. Use {@link AttributeProvider#parse(HttpServletRequest)} to parse
+ * the response.
+ *
+ * @param attributes the list of attributes to be acquired
+ * @return the personal attribute
+ * @throws UnsupportedAttributeException the unsupported attribute exception
+ * @throws ExternalAttributeRequestRequiredException an attribute request to an external service has to be done
+ */
+ public IPersonalAttributeList acquire(PersonalAttribute attributes) throws UnsupportedAttributeException, ExternalAttributeRequestRequiredException;
+
+ /**
+ * Perform redirect.
+ *
+ * @param url the return URL ending with ?artifactId=...
+ * @param citizenCountyCode the citizen county code
+ * @param req the request we got from the S-PEPS and for which we have to ask our APs
+ * @param resp the response to the preceding request
+ * @param oaParam the oa param
+ * @throws MOAIDException
+ */
+ public void performRedirect(String url, String citizenCountyCode, HttpServletRequest req, HttpServletResponse resp, OAAuthParameter oaParam) throws MOAIDException;
+
+ /**
+ * Parses the response we got from the external attribute provider.
+ *
+ * @param httpReq the http req
+ * @return a list of attributes
+ * @throws UnsupportedAttributeException if the provider cannot find anything familiar in the provided httpReq
+ * @throws MOAIDException if something went wrong
+ */
+ public IPersonalAttributeList parse(HttpServletRequest httpReq) throws UnsupportedAttributeException, MOAIDException;
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProviderFactory.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProviderFactory.java
new file mode 100644
index 000000000..98d354e8a
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProviderFactory.java
@@ -0,0 +1,57 @@
+package at.gv.egovernment.moa.id.protocols.stork2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import at.gv.egovernment.moa.id.commons.db.dao.config.AttributeProviderPlugin;
+
+/**
+ * A factory for creating AttributeProvider objects.
+ */
+public class AttributeProviderFactory {
+
+ /**
+ * Gets the available plugins.
+ *
+ * @return the available plugins
+ */
+ public static List<String> getAvailablePlugins() {
+ List<String> result = new ArrayList<String>();
+ result.add("StorkAttributeRequestProvider");
+
+ return result;
+ }
+
+ /**
+ * Creates an AttributeProvider object for the given shortname. Returns
+ * {@code null} if there is no such provider available.
+ *
+ * @param shortname
+ * the simpleName for the providers class
+ * @return the attribute provider
+ */
+ public static AttributeProvider create(String shortname, String url) {
+ switch (shortname) {
+ case "StorkAttributeRequestProvider":
+ return new StorkAttributeRequestProvider(url);
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Gets fresh instances of the configured plugins.
+ *
+ * @param configuredAPs the configured a ps
+ * @return the configured plugins
+ */
+ public static List<AttributeProvider> getConfiguredPlugins(
+ List<AttributeProviderPlugin> configuredAPs) {
+
+ List<AttributeProvider> result = new ArrayList<AttributeProvider>();
+ for(AttributeProviderPlugin current : configuredAPs)
+ result.add(create(current.getName(), current.getUrl()));
+
+ return result;
+ }
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java
index 446d942ab..d742d72ef 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java
@@ -5,6 +5,7 @@ import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.auth.stork.VelocityProvider;
import at.gv.egovernment.moa.id.moduls.IAction;
import at.gv.egovernment.moa.id.moduls.IRequest;
+import at.gv.egovernment.moa.id.storage.AssertionStorage;
import at.gv.egovernment.moa.logging.Logger;
import edu.emory.mathcs.backport.java.util.Collections;
import eu.stork.peps.auth.commons.*;
@@ -15,12 +16,18 @@ import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
-
+import org.opensaml.xml.util.Base64;
+import org.opensaml.xml.util.XMLHelper;
+import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import java.io.*;
-import java.util.ArrayList;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.HashMap;
+import eu.stork.peps.auth.engine.SAMLEngine;
/**
@@ -90,6 +97,21 @@ public class AuthenticationRequest implements IAction {
//httpResp.setStatus(200);
//VPEPSInboundPostHandler
+
+ // create fresh container
+ DataContainer container = new DataContainer();
+
+ // - fill in the request we extracted above
+ container.setRequest(request);
+
+ // - fill in the partial response created above
+ container.setResponse(response);
+
+ // - memorize the target url were we have to return the result
+ container.setTarget(target);
+
+ // see if we need to fetch further attributes
+ return (new AttributeCollector()).processRequest(container);
STORKAuthnResponse authnResponse = new STORKAuthnResponse();
@@ -244,7 +266,7 @@ public class AuthenticationRequest implements IAction {
// moaAttributeProvider.populateAttribute(attributeList, "dateOfBirth");
- return attributeList;
+ return authResponse;
}
public String getDefaultActionName() {
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DataContainer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DataContainer.java
new file mode 100644
index 000000000..40c827ef8
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DataContainer.java
@@ -0,0 +1,79 @@
+package at.gv.egovernment.moa.id.protocols.stork2;
+
+import java.io.Serializable;
+
+import eu.stork.peps.auth.commons.STORKAuthnRequest;
+import eu.stork.peps.auth.commons.STORKAuthnResponse;
+
+// TODO: Auto-generated Javadoc
+/**
+ * Holds info about an ongoing but yet incomplete stork authnrequest process.
+ */
+public class DataContainer implements Serializable {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = -8765997480582363012L;
+
+ /** The incoming request. */
+ private STORKAuthnRequest request;
+
+ /** The yet incomplete response. */
+ private STORKAuthnResponse response;
+
+ /** The target. */
+ private String target;
+
+ /**
+ * Gets the request.
+ *
+ * @return the request
+ */
+ public STORKAuthnRequest getRequest() {
+ return request;
+ }
+
+ /**
+ * Sets the request.
+ *
+ * @param request the new request
+ */
+ public void setRequest(STORKAuthnRequest request) {
+ this.request = request;
+ }
+
+ /**
+ * Gets the response.
+ *
+ * @return the response
+ */
+ public STORKAuthnResponse getResponse() {
+ return response;
+ }
+
+ /**
+ * Sets the response.
+ *
+ * @param response the new response
+ */
+ public void setResponse(STORKAuthnResponse response) {
+ this.response = response;
+ }
+
+ /**
+ * Gets the target.
+ *
+ * @return the target
+ */
+ public String getTarget() {
+ return target;
+ }
+
+ /**
+ * Sets the target.
+ *
+ * @param target the new target
+ */
+ public void setTarget(String target) {
+ this.target = target;
+ }
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoNoRedirectAttributeProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoNoRedirectAttributeProvider.java
new file mode 100644
index 000000000..e6f340c77
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoNoRedirectAttributeProvider.java
@@ -0,0 +1,48 @@
+package at.gv.egovernment.moa.id.protocols.stork2;
+
+import java.util.ArrayList;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.commons.PersonalAttributeList;
+
+/**
+ * Just a simple demoprovider who can fetch any attribute you ask him.
+ */
+public class DemoNoRedirectAttributeProvider implements AttributeProvider {
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#acquire(java.lang.String)
+ */
+ @Override
+ public IPersonalAttributeList acquire(PersonalAttribute attributeName)
+ throws UnsupportedAttributeException {
+ PersonalAttributeList requestedAttributes = new PersonalAttributeList(1);
+ requestedAttributes.add(new PersonalAttribute("sepp", true, new ArrayList<String>(), ""));
+ return requestedAttributes;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#parse(javax.servlet.http.HttpServletRequest)
+ */
+ @Override
+ public IPersonalAttributeList parse(HttpServletRequest httpReq) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#performRedirect(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public void performRedirect(String url, String citizenCountyCode,
+ HttpServletRequest req, HttpServletResponse resp, OAAuthParameter oaParam) {
+ // we should not get here
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoRedirectAttributeProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoRedirectAttributeProvider.java
new file mode 100644
index 000000000..5d4336149
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoRedirectAttributeProvider.java
@@ -0,0 +1,48 @@
+package at.gv.egovernment.moa.id.protocols.stork2;
+
+import java.util.ArrayList;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.commons.PersonalAttributeList;
+
+/**
+ * Just a simple demoprovider who can fetch any attribute you ask him.
+ */
+public class DemoRedirectAttributeProvider implements AttributeProvider {
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#acquire(java.lang.String)
+ */
+ @Override
+ public IPersonalAttributeList acquire(PersonalAttribute attributeName)
+ throws UnsupportedAttributeException, ExternalAttributeRequestRequiredException {
+ throw new ExternalAttributeRequestRequiredException(this);
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#parse(javax.servlet.http.HttpServletRequest)
+ */
+ @Override
+ public IPersonalAttributeList parse(HttpServletRequest httpReq) {
+ PersonalAttributeList requestedAttributes = new PersonalAttributeList(1);
+ requestedAttributes.add(new PersonalAttribute("sepp", true, new ArrayList<String>(), ""));
+ return requestedAttributes;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#performRedirect(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public void performRedirect(String url, String citizenCountyCode,
+ HttpServletRequest req, HttpServletResponse resp, OAAuthParameter oaParam) {
+ // we should not get here
+
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ExternalAttributeRequestRequiredException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ExternalAttributeRequestRequiredException.java
new file mode 100644
index 000000000..29b09487b
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ExternalAttributeRequestRequiredException.java
@@ -0,0 +1,14 @@
+package at.gv.egovernment.moa.id.protocols.stork2;
+
+public class ExternalAttributeRequestRequiredException extends Exception {
+ private AttributeProvider ap;
+
+ public ExternalAttributeRequestRequiredException(AttributeProvider provider) {
+ ap = provider;
+ }
+
+ public AttributeProvider getAp() {
+ return ap;
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java
index 3d7852c4b..502925a2a 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java
@@ -34,12 +34,14 @@ public class STORKProtocol implements IModulInfo, MOAIDAuthConstants {
public static final String PATH = "id_stork2";
public static final String AUTHENTICATIONREQUEST = "AuthenticationRequest";
+ public static final String ATTRIBUTE_COLLECTOR = "AttributeCollector";
private static HashMap<String, IAction> actions = new HashMap<String, IAction>();
static {
actions.put(AUTHENTICATIONREQUEST, new AuthenticationRequest());
+ actions.put(ATTRIBUTE_COLLECTOR, new AttributeCollector());
instance = new STORKProtocol();
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/StorkAttributeRequestProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/StorkAttributeRequestProvider.java
new file mode 100644
index 000000000..3c689cac9
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/StorkAttributeRequestProvider.java
@@ -0,0 +1,147 @@
+package at.gv.egovernment.moa.id.protocols.stork2;
+
+import java.io.StringWriter;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.stork.VelocityProvider;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.util.HTTPUtils;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.StringUtils;
+
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PEPSUtil;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.commons.PersonalAttributeList;
+import eu.stork.peps.auth.commons.STORKAttrQueryRequest;
+import eu.stork.peps.auth.commons.STORKAttrQueryResponse;
+import eu.stork.peps.auth.engine.STORKSAMLEngine;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
+
+/**
+ * creates a STORK attribute request for a configurable set of attributes
+ */
+public class StorkAttributeRequestProvider implements AttributeProvider {
+
+ private PersonalAttributeList requestedAttributes;
+
+ /** The destination. */
+ private String destination;
+
+ /**
+ * Instantiates a new stork attribute request provider.
+ *
+ * @param apUrl the AP location
+ */
+ public StorkAttributeRequestProvider(String apUrl) {
+ destination = apUrl;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#acquire(java.lang.String)
+ */
+ @Override
+ public IPersonalAttributeList acquire(PersonalAttribute attribute)
+ throws UnsupportedAttributeException, ExternalAttributeRequestRequiredException {
+ requestedAttributes = new PersonalAttributeList(1);
+ requestedAttributes.add(attribute);
+ throw new ExternalAttributeRequestRequiredException(this);
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#parse(javax.servlet.http.HttpServletRequest)
+ */
+ @Override
+ public IPersonalAttributeList parse(HttpServletRequest httpReq) throws MOAIDException, UnsupportedAttributeException {
+ Logger.debug("Beginning to extract SAMLResponse out of HTTP Request");
+
+ //extract STORK Response from HTTP Request
+ //Decodes SAML Response
+ byte[] decSamlToken;
+ try {
+ decSamlToken = PEPSUtil.decodeSAMLToken(httpReq.getParameter("SAMLResponse"));
+ } catch(NullPointerException e) {
+ throw new UnsupportedAttributeException();
+ }
+
+ //Get SAMLEngine instance
+ STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
+
+ STORKAttrQueryResponse attrResponse = null;
+ try {
+ //validate SAML Token
+ Logger.debug("Starting validation of SAML response");
+ attrResponse = engine.validateSTORKAttrQueryResponse(decSamlToken, (String) httpReq.getRemoteHost());
+ Logger.info("SAML response succesfully verified!");
+ }catch(STORKSAMLEngineException e){
+ Logger.error("Failed to verify STORK SAML Response", e);
+ throw new MOAIDException("stork.05", null);
+ }
+
+ return attrResponse.getPersonalAttributeList();
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#performRedirect(java.lang.String)
+ */
+ @Override
+ public void performRedirect(String url, String citizenCountryCode, HttpServletRequest req, HttpServletResponse resp, OAAuthParameter oaParam) throws MOAIDException {
+
+ String spSector = "Business";
+ String spInstitution = StringUtils.isEmpty(oaParam.getFriendlyName()) ? "UNKNOWN" : oaParam.getFriendlyName();
+ String spApplication = spInstitution;
+ String spCountry = "AT";
+
+ //generate AuthnRquest
+ STORKAttrQueryRequest attributeRequest = new STORKAttrQueryRequest();
+ attributeRequest.setDestination(destination);
+ attributeRequest.setAssertionConsumerServiceURL(url);
+ attributeRequest.setIssuer(HTTPUtils.getBaseURL(req));
+ attributeRequest.setQaa(oaParam.getQaaLevel());
+ attributeRequest.setSpInstitution(spInstitution);
+ attributeRequest.setCountry(spCountry);
+ attributeRequest.setSpApplication(spApplication);
+ attributeRequest.setSpSector(spSector);
+ attributeRequest.setPersonalAttributeList(requestedAttributes);
+
+ attributeRequest.setCitizenCountryCode(citizenCountryCode);
+
+
+ Logger.debug("STORK AttrRequest succesfully assembled.");
+
+ STORKSAMLEngine samlEngine = STORKSAMLEngine.getInstance("VIDP");
+ try {
+ attributeRequest = samlEngine.generateSTORKAttrQueryRequest(attributeRequest);
+ } catch (STORKSAMLEngineException e) {
+ Logger.error("Could not sign STORK SAML AttrRequest.", e);
+ throw new MOAIDException("stork.00", null);
+ }
+
+ Logger.info("STORK AttrRequest successfully signed!");
+
+ try {
+ Logger.trace("Initialize VelocityEngine...");
+
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/saml2-post-binding-moa.vm");
+ VelocityContext context = new VelocityContext();
+ context.put("SAMLRequest", PEPSUtil.encodeSAMLToken(attributeRequest.getTokenSaml()));
+ context.put("action", destination);
+
+ StringWriter writer = new StringWriter();
+ template.merge(context, writer);
+
+ resp.getOutputStream().write(writer.toString().getBytes());
+ } catch (Exception e) {
+ Logger.error("Error sending STORK SAML AttrRequest.", e);
+ throw new MOAIDException("stork.11", null);
+ }
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/UnsupportedAttributeException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/UnsupportedAttributeException.java
new file mode 100644
index 000000000..9447c079f
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/UnsupportedAttributeException.java
@@ -0,0 +1,7 @@
+package at.gv.egovernment.moa.id.protocols.stork2;
+
+public class UnsupportedAttributeException extends Exception {
+
+ private static final long serialVersionUID = -7720066381435378111L;
+
+}
diff --git a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties
index 2559d3d18..0e252e981 100644
--- a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties
+++ b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties
@@ -205,6 +205,8 @@ stork.07=Es existiert kein STORK AuthnRequest f\u00FCr diese STORK Response
stork.08=STORK SAML Assertion Validierung fehlgeschlagen
stork.09=Fehler beim \u00FCberpr\u00FCfen der STORK B\u00FCrgerInnen Signatur
stork.10=Fehler in der Verbindung zum SZR-Gateway
+stork.11=Fehler beim Sammeln von StorkAttributen
+stork.12=Konnte keine VIDP Konfiguration finden
pvp2.00={0} ist kein gueltiger consumer service index
pvp2.01=Fehler beim kodieren der PVP2 Antwort
diff --git a/id/server/moa-id-commons/src/main/resources/config/moaid_config_2.0.xsd b/id/server/moa-id-commons/src/main/resources/config/moaid_config_2.0.xsd
index e6705dbb8..d20ec1c68 100644
--- a/id/server/moa-id-commons/src/main/resources/config/moaid_config_2.0.xsd
+++ b/id/server/moa-id-commons/src/main/resources/config/moaid_config_2.0.xsd
@@ -49,7 +49,7 @@
<xsd:extension base="xsd:string"/>
</xsd:simpleContent>
</xsd:complexType>
- <xsd:element name="AbstractSimpleIdentification" type="StorkAttribute">
+ <xsd:element name="AbstractSimpleIdentification" type="AttributeProviderPlugin">
<xsd:annotation>
<xsd:documentation>possibility to include common austrian primary
keys in human readable way, english translation not available
@@ -884,6 +884,8 @@
<xsd:element name="StorkLogonEnabled" type="xsd:boolean"/>
<xsd:element ref="Qaa" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="OAAttributes" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="VidpEnabled" type="xsd:boolean"></xsd:element>
+ <xsd:element ref="AttributeProviders" maxOccurs="unbounded" minOccurs="0"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
@@ -950,6 +952,15 @@
<xsd:element name="OnlyMandateLoginAllowed" type="xsd:boolean" default="false" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
+
+ <xsd:complexType name="AttributeProviderPlugin">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"></xsd:element>
+ <xsd:element name="url" type="xsd:anyURI"></xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="AttributeProviders" type="AttributeProviderPlugin"></xsd:element>
<xsd:element name="Attributes" type="StorkAttribute"/>
<xsd:element name="Qaa" type="QualityAuthenticationAssuranceLevelType"/>
<xsd:complexType name="OAStorkAttribute">