diff options
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment')
21 files changed, 1184 insertions, 9 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java index bebae89db..ce5aa15c3 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java @@ -1875,7 +1875,7 @@ public class AuthenticationServer implements MOAIDAuthConstants { CPEPS cpeps = storkConfig.getCPEPS(moasession.getCcc()); - Logger.debug("Preparing to assemble STORK AuthnRequest witt the following values:"); + Logger.debug("Preparing to assemble STORK AuthnRequest with the following values:"); String destination = cpeps.getPepsURL().toExternalForm(); Logger.debug("C-PEPS URL: " + destination); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java index d6d22fe4a..479775dd5 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java @@ -110,9 +110,11 @@ public class SignatureVerificationInvoker { authConnParam = authConfigProvider.getMoaSpConnectionParameter(); //If the ConnectionParameter do NOT exist, we try to get the api to work.... if (authConnParam != null) { + Logger.debug("Connecting using auth url: " + authConnParam.getUrl() + ", service " + serviceName.getNamespaceURI() + " : " + serviceName.getLocalPart() + " : "+ serviceName.getPrefix()); endPoint = authConnParam.getUrl(); call.setTargetEndpointAddress(endPoint); responses = (Vector) call.invoke(serviceName, params); + Logger.debug("Got responses: " + responses.size()); // TODO handle axis 302 response when incorrect service url is used response = (SOAPBodyElement) responses.get(0); return response.getAsDOM(); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java index b356c6f35..41be2c7e3 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java @@ -331,6 +331,7 @@ public class PEPSConnectorServlet extends AuthServlet { //TODO: found better solution, but QAA Level in response could be not supported yet
try {
+
moasession.setQAALevel(authnResponse.getAssertions().get(0).
getAuthnStatements().get(0).getAuthnContext().
getAuthnContextClassRef().getAuthnContextClassRef());
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java index 0d39a4bc5..7e248243b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java @@ -123,11 +123,12 @@ public class VerifyXMLSignatureResponseValidator { checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.24", null); if (verifyXMLSignatureResponse.getCertificateCheckCode() == 5) checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.25", null); - - if (whatToCheck.equals(CHECK_IDENTITY_LINK)) - throw new ValidateException("validator.07", new Object[] { checkFailedReason } ); - else - throw new ValidateException("validator.19", new Object[] { checkFailedReason } ); + + // TEST CARDS + // if (whatToCheck.equals(CHECK_IDENTITY_LINK)) + // throw new ValidateException("validator.07", new Object[] { checkFailedReason } ); + // else + // throw new ValidateException("validator.19", new Object[] { checkFailedReason } ); } if (ignoreManifestValidationResult) { 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..881d3bb2a 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,8 @@ 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 ff481b825..ab106e3c0 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,8 +65,9 @@ public class STORKConfig { this.props = props;
//create CPEPS map
- 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 = 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
+
cpepsMap = new HashMap<String, CPEPS>();
if (cpeps != null) {
@@ -76,8 +83,20 @@ 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>();
if (stork.getAttributes() != null) {
for(StorkAttribute current : stork.getAttributes()) {
@@ -87,6 +106,8 @@ public class STORKConfig { }
+ }
+
public SignatureCreationParameter getSignatureCreationParameter() {
return new SignatureCreationParameter(props, basedirectory);
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java index c9fc07b70..3af8bcfe5 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java @@ -510,6 +510,8 @@ public class DispatcherServlet extends AuthServlet{ ConfigurationDBUtils.closeSession(); } + Logger.info("Clossing Dispatcher processing loop"); + Logger.info("Http response prepared sent: " + resp.toString()); } @Override diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ModulStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ModulStorage.java index 91f98608c..4a1da76e2 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ModulStorage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ModulStorage.java @@ -33,6 +33,7 @@ public class ModulStorage { private static final String[] modulClasses = new String[]{ "at.gv.egovernment.moa.id.protocols.saml1.SAML1Protocol", "at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol", + "at.gv.egovernment.moa.id.protocols.stork2.STORKProtocol", "at.gv.egovernment.moa.id.protocols.oauth20.protocol.OAuth20Protocol" }; 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..c1a61904d --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java @@ -0,0 +1,165 @@ +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"; + + /** The return url. */ + // TODO find correct return URL + // HTTPUtils.getBaseURL(req); + private String returnUrl = "findCorrectReturnURL"; + + /* (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(); + + // - put container in temporary store. + AssertionStorage.getInstance().put(newArtifactId, container); + + // add container-key to redirect embedded within the return URL + e.getAp().performRedirect(returnUrl + "?" + 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 new file mode 100644 index 000000000..1f6ffaa9a --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java @@ -0,0 +1,175 @@ +package at.gv.egovernment.moa.id.protocols.stork2; + +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +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 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.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.HashMap; +import eu.stork.peps.auth.engine.SAMLEngine; + +/** + * @author bsuzic + * Date: 12/3/13, Time: 2:08 PM + */ + +public class AuthenticationRequest implements IAction { + /* + Second request step - after authentication of the user is done and moasession obtained, + process request and forward the user further to PEPS and/or other entities + */ + + + private VelocityEngine velocityEngine; + + + public String processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, AuthenticationSession moasession) throws MOAIDException { + Logger.debug("Starting AuthenticationRequest"); + //AuthenticationServer.getInstance().startSTORKAuthentication(httpReq, httpResp, moasession); + Logger.debug("Http Response: " + httpResp.toString() + ", "); + Logger.debug("Moa session: " + moasession.toString() + " " + moasession.getOAURLRequested() + " " + moasession.getPublicOAURLPrefix() + " " + moasession.getAction() + " " + moasession.getIdentityLink().getName() + " " + moasession.getTarget()); + httpResp.reset(); + //httpResp.addHeader("Location", "http:/www.google.com"); + if (req instanceof STORKAuthnRequestDEL) { + /* + 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 + + // 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); + } + + public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) { + return true; + } + + + /* + + public StartAuthResponse getStartAuthResponse(STORKAuthnRequest authnRequest) { + + StartAuthResponse authResponse = new StartAuthResponse(500, null, new HashMap<String, String>()); + + if (authnRequest.getSPID() != null) { + Logger.debug("SP id: " + authnRequest.getSPID()); + } else { + SpInstitution spInstitution = (SpInstitution)authnRequest.getExtensions().getUnknownXMLObjects(SpInstitution.DEFAULT_ELEMENT_NAME).get(0); + Logger.debug("SP institution: " + spInstitution.getValue()); + } + + Logger.debug("SPEPS issuer: " + authnRequest.getIssuer().getValue()); + Logger.debug("SPEPS Consumer URL: " + authnRequest.getAssertionConsumerServiceURL()); + + + + try { + + initVelocityEngine(); + VelocityContext velocityContext = new VelocityContext(); + + velocityContext.put("action", authnRequest.getDestination()); + if (authnRequest.getDOM() == null) { + SAMLUtil.marshallMessage(authnRequest); + } + + String messageXML = XMLHelper.nodeToString(authnRequest.getDOM()); + String encodedMessage = Base64.encodeBytes(messageXML.getBytes("UTF-8"), Base64.DONT_BREAK_LINES); + velocityContext.put("SAMLRequest", encodedMessage); + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + + Writer out = new OutputStreamWriter(outStream, "UTF-8"); + velocityEngine.mergeTemplate("/templates/saml2-post-binding.vm", "UTF-8", velocityContext, out); + out.flush(); + authResponse.setContent(outStream.toByteArray()); + + authResponse.addHeader("Content-Type", "text/html; charset=utf-8"); + authResponse.addHeader("Cache-Control", "no-cache"); + authResponse.setHttpStatusCode(200); + + } catch (Exception e) { + Logger.error("ERROR"); + } + + + return authResponse; + } + + */ + + public String getDefaultActionName() { + return STORKProtocol.AUTHENTICATIONREQUEST; + } + + + private void initVelocityEngine() throws Exception { + velocityEngine = new VelocityEngine(); + velocityEngine.setProperty(RuntimeConstants.ENCODING_DEFAULT, "UTF-8"); + velocityEngine.setProperty(RuntimeConstants.OUTPUT_ENCODING, "UTF-8"); + velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); + velocityEngine.setProperty("classpath.resource.loader.class", + "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + + velocityEngine.init(); + } + +} 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/STORKAuthnReq.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKAuthnReq.java new file mode 100644 index 000000000..54072b6a3 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKAuthnReq.java @@ -0,0 +1,105 @@ +package at.gv.egovernment.moa.id.protocols.stork2; + +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.protocols.pvp2x.binding.MOAURICompare; +import at.gv.egovernment.moa.logging.Logger; +import eu.stork.peps.auth.commons.STORKAuthnRequest; +import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.saml2.binding.decoding.HTTPPostDecoder; +import org.opensaml.ws.transport.http.HTTPInTransport; + + +/** + * @author bsuzic + * Date: 1/22/14, Time: 5:30 PM + */ +public class STORKAuthnReq implements IRequest { + private String requestID; + private String target = null; + String module = null; + String action = null; + private STORKAuthnRequest storkAuthnRequest; + + public void setSTORKAuthnRequest(STORKAuthnRequest request) { + this.storkAuthnRequest = request; + } + + public STORKAuthnRequest getStorkAuthnRequest() { + return this.storkAuthnRequest; + } + + public void createStorkReq(HTTPInTransport profileReq) { + Logger.debug("Generate stork request test..."); + storkAuthnRequest = new STORKAuthnRequest(); + + BasicSAMLMessageContext samlMessageContext = new BasicSAMLMessageContext(); + samlMessageContext.setInboundMessageTransport(profileReq); + + HTTPPostDecoder postDecoder = new HTTPPostDecoder(); + postDecoder.setURIComparator(new MOAURICompare()); // TODO Abstract to use general comparator + + try { + Logger.debug("Attempting to decode request..."); + postDecoder.decode(samlMessageContext); + } catch (Exception e) { + Logger.error("Error decoding STORKAuthnRequest", e); + } + + + + //storkAuthnRequest = (STORKAuthnRequest)samlMessageContext.getInboundSAMLMessage(); + //samlMessageContext.getinbound + //storkAuthnRequest.set + + + + } + + + + public String getOAURL() { + return "https://sp:8889/SP"; // + } + + public boolean isPassiv() { + return false; // + } + + public boolean forceAuth() { + return false; // + } + + public boolean isSSOSupported() { + return false; // + } + + public String requestedModule() { + return this.module; // + } + + public String requestedAction() { + return action; // + } + + public void setModule(String module) { + this.module = module; + } + + public void setAction(String action) { + this.action = action; + } + + public String getTarget() { + return this.target; // + } + + public void setRequestID(String id) { + this.requestID = id; + } + + public String getRequestID() { + return this.requestID; // + } + + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKAuthnRequestDEL.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKAuthnRequestDEL.java new file mode 100644 index 000000000..c8a5ac84d --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKAuthnRequestDEL.java @@ -0,0 +1,71 @@ +package at.gv.egovernment.moa.id.protocols.stork2; + +import at.gv.egovernment.moa.id.moduls.IRequest; +import eu.stork.peps.auth.commons.STORKAuthnRequest; +import org.opensaml.common.xml.SAMLConstants; + +/** + * @author bsuzic + * Date: 12/4/13, Time: 6:31 PM + */ +//public class STORKAuthnRequestDEL extends STORKAuthnRequestImpl implements IRequest { + +public class STORKAuthnRequestDEL implements IRequest { + private String requestID; + private String target = null; + String module = null; + String action = null; + private STORKAuthnRequest storkAuthnRequest; + + public void setSTORKAuthnRequest(STORKAuthnRequest request) { + this.storkAuthnRequest = request; + } + + public STORKAuthnRequest getStorkAuthnRequest() { + return this.storkAuthnRequest; + } + + public String getOAURL() { + return "https://sp:8889/SP"; // + } + + public boolean isPassiv() { + return false; // + } + + public boolean forceAuth() { + return false; // + } + + public boolean isSSOSupported() { + return false; // + } + + public String requestedModule() { + return this.module; // + } + + public String requestedAction() { + return action; // + } + + public void setModule(String module) { + this.module = module; + } + + public void setAction(String action) { + this.action = action; + } + + public String getTarget() { + return this.target; // + } + + public void setRequestID(String id) { + this.requestID = id; + } + + public String getRequestID() { + return this.requestID; // + } +} 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 new file mode 100644 index 000000000..318a8fc9c --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java @@ -0,0 +1,175 @@ +package at.gv.egovernment.moa.id.protocols.stork2; + +import at.gv.egovernment.moa.id.auth.AuthenticationServer; +import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.moduls.IAction; +import at.gv.egovernment.moa.id.moduls.IModulInfo; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.protocols.pvp2x.binding.MOAURICompare; +import at.gv.egovernment.moa.logging.Logger; +import eu.stork.peps.auth.commons.PEPSUtil; +import eu.stork.peps.auth.commons.STORKAuthnResponse; +import eu.stork.peps.auth.engine.STORKSAMLEngine; +import eu.stork.peps.exceptions.STORKSAMLEngineException; +import org.opensaml.common.binding.BasicSAMLMessageContext; +import org.opensaml.saml2.binding.decoding.HTTPPostDecoder; +import org.opensaml.ws.transport.http.HTTPInTransport; +import org.opensaml.ws.transport.http.HTTPOutTransport; +import org.opensaml.ws.transport.http.HttpServletRequestAdapter; +import org.opensaml.ws.transport.http.HttpServletResponseAdapter; +import eu.stork.peps.auth.commons.STORKAuthnRequest; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Collections; +import java.util.HashMap; + +/** + * Stork 2 Protocol Support + * Date: 11/29/13, Time: 12:32 PM + * @author bsuzic + */ +public class STORKProtocol implements IModulInfo, MOAIDAuthConstants { + + public static final String NAME = STORKProtocol.class.getName(); + 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(); + } + + private static STORKProtocol instance = null; + + + public String getName() { + return NAME; + } + + public String getPath() { + return PATH; + } + + public IAction getAction(String action) { + return actions.get(action); + } + + public STORKProtocol() { + super(); // + } + + /* + First request step - send it to BKU selection for user authentication. After the user credentials + and other info are obtained, in the second step the request will be processed and the user redirected + */ + public IRequest preProcess(HttpServletRequest request, HttpServletResponse response, String action) throws MOAIDException { + Logger.debug("Starting preprocessing"); + Logger.debug("Got request: " + request.toString()); + Logger.debug("Request method: " + request.getMethod()); + for (Object o : Collections.list(request.getHeaderNames())) { + Logger.debug("Request header: " + o.toString() + ":::" + request.getHeader(o.toString())); + } + for (Object o : Collections.list(request.getParameterNames())) { + Logger.debug("Request parameter: " + o.toString() + "::::" + request.getParameter(o.toString())); + } + + Logger.debug("Request content length: " + request.getContentLength()); + Logger.debug("Request query: " + request.getQueryString()); + Logger.debug("Response: " + response.toString()); + Logger.debug("Action: " + action); + + Logger.debug("Processing saml request"); + String SAMLRequest = request.getParameter("SAMLRequest"); + + HTTPInTransport profileReq = new HttpServletRequestAdapter(request); + HTTPOutTransport profileResp = new HttpServletResponseAdapter(response, request.isSecure()); + + + BasicSAMLMessageContext samlMessageContext = new BasicSAMLMessageContext(); + samlMessageContext.setInboundMessageTransport(profileReq); + + HTTPPostDecoder postDecoder = new HTTPPostDecoder(); + postDecoder.setURIComparator(new MOAURICompare()); // TODO Abstract to use general comparator + + try { + Logger.debug("Attempting to decode request..."); + postDecoder.decode(samlMessageContext); + } catch (Exception e) { + Logger.error("Error decoding STORKAuthnRequest", e); + } + /* + + STORKAuthnRequestImpl ST2Req = (STORKAuthnRequestImpl)samlMessageContext.getInboundSAMLMessage(); + //STORKAuthnRequestDEL STORK2Request = (STORKAuthnRequestDEL)samlMessageContext.getInboundSAMLMessage(); + STORKAuthnRequestDEL STORK2Request = new STORKAuthnRequestDEL(); + STORK2Request.setSTORKAuthnRequest(ST2Req); + + Logger.debug("STORK2 Citizen code: " + ST2Req.getCitizenCountryCode()); + Logger.debug("STORK2 QAA: " + ST2Req.getQAALevel()); + Logger.debug("STORK2 ISSUER: " + ST2Req.getIssuer().toString()); + + */ + STORKAuthnReq storkAuthnReq = new STORKAuthnReq(); + + + STORKAuthnRequestDEL STORK2Request = new STORKAuthnRequestDEL(); + + + //extract STORK Response from HTTP Request + //Decodes SAML Response + + + byte[] decSamlToken; + try { + decSamlToken = PEPSUtil.decodeSAMLToken(request.getParameter("SAMLRequest")); + } catch(NullPointerException e) { + Logger.error("Unable to retrieve STORK Response", e); + throw new MOAIDException("stork.04", null); + } + + //Get SAMLEngine instance + STORKSAMLEngine engine = STORKSAMLEngine.getInstance("incoming"); + + STORKAuthnRequest authnRequest = null; + Logger.error("decsamltoken" +decSamlToken.toString()); + + try { + authnRequest = engine.validateSTORKAuthnRequest(decSamlToken); + } catch (STORKSAMLEngineException ex) { + Logger.error("Unable to validate storkrkauthnreqeust" + ex.getMessage() ); + } + + Logger.error("acsu " + authnRequest.getAssertionConsumerServiceURL()); + Logger.error("cc " + authnRequest.getCitizenCountryCode()); + Logger.error("iss " + authnRequest.getIssuer()); + Logger.error("spid " + authnRequest.getSPID()); + Logger.error("spi " + authnRequest.getSpInstitution()); + + + + return STORK2Request; + } + + public IAction canHandleRequest(HttpServletRequest request, HttpServletResponse response) { + return null; + } + + public boolean generateErrorMessage(Throwable e, HttpServletRequest request, HttpServletResponse response, IRequest protocolRequest) throws Throwable { + return false; + } + + public boolean validate(HttpServletRequest request, HttpServletResponse response, IRequest pending) { + return false; + } +} + + 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; + +} |