diff options
author | Thomas Lenz <tlenz@iaik.tugraz.at> | 2016-03-30 16:44:02 +0200 |
---|---|---|
committer | Thomas Lenz <tlenz@iaik.tugraz.at> | 2016-03-30 16:44:02 +0200 |
commit | 38a8abe06596847cda4e4fd9d5b4f5585c67fc52 (patch) | |
tree | cffa694dab353f654f55a6b57ce030f8c3e4673c /id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols | |
parent | 88fe47db569a262a4631e002187f54979d1ab9a6 (diff) | |
download | moa-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')
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(); } |