aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas
diff options
context:
space:
mode:
authorThomas Lenz <tlenz@iaik.tugraz.at>2016-03-30 16:44:02 +0200
committerThomas Lenz <tlenz@iaik.tugraz.at>2016-03-30 16:44:02 +0200
commit38a8abe06596847cda4e4fd9d5b4f5585c67fc52 (patch)
treecffa694dab353f654f55a6b57ce030f8c3e4673c /id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas
parent88fe47db569a262a4631e002187f54979d1ab9a6 (diff)
downloadmoa-id-spss-38a8abe06596847cda4e4fd9d5b4f5585c67fc52.tar.gz
moa-id-spss-38a8abe06596847cda4e4fd9d5b4f5585c67fc52.tar.bz2
moa-id-spss-38a8abe06596847cda4e4fd9d5b4f5585c67fc52.zip
implement first parts of eIDAS module error handling and error-response messaging
Diffstat (limited to 'id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas')
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java139
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java6
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java4
3 files changed, 139 insertions, 10 deletions
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java
index 1996c3d7c..24134f1d9 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java
@@ -23,17 +23,30 @@
package at.gv.egovernment.moa.id.protocols.eidas;
import java.io.IOException;
+import java.io.StringWriter;
+import java.util.List;
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 org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.metadata.AssertionConsumerService;
+import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
-import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.frontend.velocity.VelocityProvider;
import at.gv.egovernment.moa.id.auth.modules.eidas.Constants;
+import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider;
+import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASMetadataProviderDecorator;
+import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASAuthnRequestProcessingException;
+import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASAuthnRequestValidationException;
+import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASException;
import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAPersonalAttributeList;
import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils;
import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters;
@@ -44,8 +57,11 @@ import at.gv.egovernment.moa.id.protocols.AbstractAuthProtocolModulController;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.MiscUtil;
import eu.eidas.auth.commons.EIDASAuthnRequest;
+import eu.eidas.auth.commons.EIDASAuthnResponse;
import eu.eidas.auth.commons.EIDASUtil;
import eu.eidas.auth.engine.EIDASSAMLEngine;
+import eu.eidas.auth.engine.metadata.MetadataUtil;
+import eu.eidas.engine.exceptions.EIDASSAMLEngineException;
/**
* eIDAS Protocol Support for outbound authentication and metadata generation
@@ -140,7 +156,7 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController {
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 void preProcess(HttpServletRequest request, HttpServletResponse response, EIDASData pendingReq) throws MOAIDException {
+ private void preProcess(HttpServletRequest request, HttpServletResponse response, EIDASData pendingReq) throws MOAIDException {
Logger.info("received an eIDaS request");
@@ -177,13 +193,36 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController {
samlReq.setPersonalAttributeList(pendingReq.getEidasRequestedAttributes()); // circumvent non-serializable eidas personal attribute list
pendingReq.setEidasRequest(samlReq);
+ //validate destination against metadata
+ String reqDestination = samlReq.getDestination();
+ if (MiscUtil.isNotEmpty(reqDestination)) {
+ boolean isValid = false;
+ List<AssertionConsumerService> allowedAssertionConsumerUrl = new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance())
+ .getSPSSODescriptor(samlReq.getIssuer()).getAssertionConsumerServices();
+
+ for (AssertionConsumerService el : allowedAssertionConsumerUrl) {
+ if (reqDestination.equals(el.getLocation()))
+ isValid = true;
+
+ }
+
+ if (!isValid) {
+ Logger.info("eIDAS AuthnRequest contains a not valid 'Destination' attribute");
+ throw new eIDASAuthnRequestValidationException("stork.01",
+ new Object[]{"eIDAS AuthnRequest contains a not valid 'Destination' attribute"});
+ }
+
+ }
+
+
// - memorize OA url
pendingReq.setOAURL(samlReq.getIssuer());
// - memorize OA config
IOAAuthParameters oaConfig = authConfig.getOnlineApplicationParameter(pendingReq.getOAURL());
if (oaConfig == null)
- throw new AuthenticationException("stork.12", new Object[]{pendingReq.getOAURL()});
+ throw new eIDASAuthnRequestProcessingException("eIDAS.08", new Object[]{pendingReq.getOAURL()});
+
pendingReq.setOnlineApplicationConfiguration(oaConfig);
String spType = samlReq.getSPType();
@@ -194,16 +233,102 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController {
}
Logger.debug("eIDAS request has SPType:" + spType);
+
+ } catch (MOAIDException e) {
+ Logger.info("eIDAS AuthnRequest preProcessing FAILED. Msg:" + e.getMessage());
+ throw e;
+
+ } catch (EIDASSAMLEngineException e) {
+ Logger.info("eIDAS AuthnRequest preProcessing FAILED. Msg:" + e.getMessage());
+ throw new eIDASAuthnRequestProcessingException("eIDAS.06", new Object[]{e.getMessage()}, e);
} catch(Exception e) {
- Logger.error("error in preprocessing step", e);
- throw new MOAIDException("error in preprocessing step", null);
+ Logger.warn("eIDAS AuthnRequest preProcessing FAILED. Msg:" + e.getMessage(), e);
+ throw new eIDASAuthnRequestProcessingException("eIDAS.06", new Object[]{e.getMessage()}, e);
}
}
- public boolean generateErrorMessage(Throwable e, HttpServletRequest request, HttpServletResponse response, IRequest protocolRequest) throws Throwable {
- return false;
+ public boolean generateErrorMessage(Throwable e, HttpServletRequest request, HttpServletResponse response, IRequest pendingReq) throws Throwable {
+ if (pendingReq != null && pendingReq instanceof EIDASData) {
+ EIDASData eidasReq = (EIDASData) pendingReq;
+ if (eidasReq.getEidasRequest() == null) {
+ Logger.info("Can not build eIDAS ErrorResponse. No eIDAS AuthnRequest found.");
+ return false;
+ }
+
+ try {
+ EIDASAuthnResponse eIDASResp = new EIDASAuthnResponse();
+ eIDASResp.setIssuer(pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_METADATA);
+
+ if (e instanceof eIDASException) {
+ eIDASResp.setStatusCode(((eIDASException) e).getStatusCodeFirstLevel());
+ eIDASResp.setSubStatusCode(((eIDASException) e).getStatusCodeSecondLevel());
+ eIDASResp.setMessage(e.getMessage());
+
+ } else if (e instanceof MOAIDException ) {
+ eIDASResp.setStatusCode(StatusCode.RESPONDER_URI);
+ eIDASResp.setSubStatusCode(StatusCode.AUTHN_FAILED_URI);
+ eIDASResp.setMessage(e.getMessage());
+
+ } else {
+ eIDASResp.setStatusCode(StatusCode.RESPONDER_URI);
+ eIDASResp.setSubStatusCode(StatusCode.AUTHN_FAILED_URI);
+ eIDASResp.setMessage(e.getMessage());
+
+ }
+
+
+ EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine();
+
+ if(null == eidasReq.getEidasRequest().getAssertionConsumerServiceURL()) {
+ String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata(
+ new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()),
+ engine,
+ eidasReq.getEidasRequest());
+ eidasReq.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl);
+
+ }
+ //get eIDAS SAML-engine
+
+ eIDASResp = engine.generateEIDASAuthnResponseFail(eidasReq.getEidasRequest(), eIDASResp,
+ eidasReq.getRemoteAddress(), true);
+
+ String token = EIDASUtil.encodeSAMLToken(eIDASResp.getTokenSaml());
+
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/stork2_postbinding_template.html");
+ VelocityContext context = new VelocityContext();
+
+ context.put("RelayState", eidasReq.getRemoteRelayState());
+
+ context.put("SAMLResponse", token);
+ Logger.debug("SAMLResponse original: " + token);
+
+ Logger.debug("Putting assertion consumer url as action: " + eidasReq.getEidasRequest().getAssertionConsumerServiceURL());
+ context.put("action", eidasReq.getEidasRequest().getAssertionConsumerServiceURL());
+ Logger.trace("Starting template merge");
+ StringWriter writer = new StringWriter();
+
+ Logger.trace("Doing template merge");
+ template.merge(context, writer);
+ Logger.trace("Template merge done");
+
+ Logger.trace("Sending html content : " + new String(writer.getBuffer()));
+
+ response.getOutputStream().write(writer.getBuffer().toString().getBytes("UTF-8"));
+ response.setContentType(MediaType.TEXT_HTML.getType());
+
+ return true;
+
+ } catch (Exception e1 ) {
+ Logger.error("Generate eIDAS Error-Response failed.", e);
+
+ }
+
+ }
+
+ return false;
}
public boolean validate(HttpServletRequest request, HttpServletResponse response, IRequest pending) {
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java
index 60ffb3673..b4db5c83d 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java
@@ -71,8 +71,10 @@ public class EidasMetaDataRequest implements IAction {
httpResp.setContentType(MediaType.APPLICATION_XML.getType());
httpResp.getWriter().print(metaData);
httpResp.flushBuffer();
- } catch (Exception e) {
- e.printStackTrace();
+ } catch (Exception e) {
+ Logger.error("eIDAS Metadata generation FAILED.", e);
+ throw new MOAIDException("eIDAS.05", new Object[]{e.getMessage()}, e);
+
}
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java
index d9663092f..9943cc5fb 100644
--- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java
+++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java
@@ -122,19 +122,21 @@ public class eIDASAuthenticationRequest implements IAction {
// but we need to set the appropriate request issuer
engine.setRequestIssuer(eidasRequest.getEidasRequest().getIssuer());
- // check if we have the destination available, supply it if not
+
if(null == eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()) {
String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata(
new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()),
engine,
eidasRequest.getEidasRequest());
eidasRequest.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl);
+
}
response = engine.generateEIDASAuthnResponse(eidasRequest.getEidasRequest(), response, eidasRequest.getRemoteAddress(), true);
token = EIDASUtil.encodeSAMLToken(response.getTokenSaml());
+
} catch(Exception e) {
e.printStackTrace();
}