aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java
diff options
context:
space:
mode:
authorThomas Lenz <tlenz@iaik.tugraz.at>2016-08-12 11:48:05 +0200
committerThomas Lenz <tlenz@iaik.tugraz.at>2016-08-12 11:48:05 +0200
commitd71a87f12afb08371a3f50030f183a89d9e319ca (patch)
tree1db7c016e9dd81aaa38c839bfd724e4c40135262 /id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java
parent404dae436be7d6e7d381ae183745e4edaac2a866 (diff)
downloadmoa-id-spss-d71a87f12afb08371a3f50030f183a89d9e319ca.tar.gz
moa-id-spss-d71a87f12afb08371a3f50030f183a89d9e319ca.tar.bz2
moa-id-spss-d71a87f12afb08371a3f50030f183a89d9e319ca.zip
fix a lot of problems which occur with new eIDAS SAML Engine v1.1.0
Diffstat (limited to 'id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java')
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java135
1 files changed, 93 insertions, 42 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 cf9414a3b..cb91d5fa3 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
@@ -34,6 +34,7 @@ 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.opensaml.saml2.metadata.EntityDescriptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
@@ -49,6 +50,7 @@ import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASAuthnRequestP
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.SAMLEngineUtils;
+import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants;
import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters;
import at.gv.egovernment.moa.id.commons.api.IRequest;
import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException;
@@ -59,6 +61,8 @@ import at.gv.egovernment.moa.util.MiscUtil;
import eu.eidas.auth.commons.EidasStringUtil;
import eu.eidas.auth.commons.protocol.IAuthenticationRequest;
import eu.eidas.auth.commons.protocol.IResponseMessage;
+import eu.eidas.auth.commons.protocol.eidas.IEidasAuthenticationRequest;
+import eu.eidas.auth.commons.protocol.eidas.impl.EidasAuthenticationRequest;
import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse;
import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse.Builder;
import eu.eidas.auth.engine.ProtocolEngineI;
@@ -74,7 +78,7 @@ import eu.eidas.engine.exceptions.EIDASSAMLEngineException;
public class EIDASProtocol extends AbstractAuthProtocolModulController {
public static final String NAME = EIDASProtocol.class.getName();
- public static final String PATH = "eidas";
+ public static final String PATH = "eidas";
@Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider;
@@ -169,7 +173,7 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController {
String base64SamlToken = request.getParameter("SAMLRequest");
if (MiscUtil.isEmpty(base64SamlToken)) {
Logger.warn("No eIDAS SAMLRequest found in http request.");
- throw new MOAIDException("HTTP request includes no eIDAS SAML-Request element.", null);
+ throw new MOAIDException("eIDAS.06", new Object[]{"HTTP request includes no eIDAS SAML-Request element."});
}
try {
@@ -178,34 +182,29 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController {
//get eIDAS SAML-engine
ProtocolEngineI engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider);
-
- //TODO: change to configurable COUNTRY-CODE
- String cititzenCountryCode = "AT";
- //validate SAML token
- IAuthenticationRequest samlReq = engine.unmarshallRequestAndValidate(decSamlToken, cititzenCountryCode );
-
- // - memorize remote ip
- pendingReq.setRemoteAddress(request.getRemoteAddr());
-
- // - memorize relaystate
- String relayState = request.getParameter("RelayState");
- pendingReq.setRemoteRelayState(relayState);
-
- // - memorize country code of target country
- pendingReq.setGenericDataToSession(
- RequestImpl.eIDAS_GENERIC_REQ_DATA_COUNTRY, samlReq.getOriginCountryCode());
- //TODO: store level of assurance
+ String cititzenCountryCode =
+ authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE,
+ MOAIDAuthConstants.COUNTRYCODE_AUSTRIA);
- // - memorize requested attributes
- pendingReq.setEidasRequestedAttributes(samlReq.getRequestedAttributes());
+ //****************************************
+ //***** validate eIDAS request *********
+ //****************************************
+ //validate SAML token
+ IAuthenticationRequest samlReq = engine.unmarshallRequestAndValidate(decSamlToken, cititzenCountryCode );
- // - memorize whole request
- pendingReq.setEidasRequest(samlReq);
-
+ //validate internal JAVA class type
+ if (!(samlReq instanceof IEidasAuthenticationRequest)) {
+ Logger.error("eIDAS AuthnRequst from node:" + samlReq.getIssuer()
+ + " is NOT from Type:" + IEidasAuthenticationRequest.class.getName());
+ throw new MOAIDException("eIDAS.06", new Object[]{"eIDAS AuthnRequest maps to an wrong internal Type."});
+
+ }
+ IEidasAuthenticationRequest eIDASSamlReq = (IEidasAuthenticationRequest) samlReq;
+
//validate Destination against MOA-ID-Auth configuration
- String reqDestination = samlReq.getDestination();
+ String reqDestination = eIDASSamlReq.getDestination();
if (MiscUtil.isEmpty(reqDestination) ||
!reqDestination.startsWith(pendingReq.getAuthURL())) {
Logger.info("eIDAS AuthnRequest contains a not valid 'Destination' attribute");
@@ -213,13 +212,16 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController {
new Object[]{"eIDAS AuthnRequest contains a not valid 'Destination' attribute"});
}
-
+
//validate AssertionConsumerServiceURL against metadata
- String reqAssertionConsumerServiceURL = samlReq.getAssertionConsumerServiceURL();
+ EntityDescriptor eIDASNodeEntityDesc = new MOAeIDASMetadataProviderDecorator(eIDASMetadataProvider)
+ .getEntityDescriptor(eIDASSamlReq.getIssuer(), SAMLEngineUtils.getMetadataSigner());
+
+ String reqAssertionConsumerServiceURL = eIDASSamlReq.getAssertionConsumerServiceURL();
if (MiscUtil.isNotEmpty(reqAssertionConsumerServiceURL)) {
- boolean isValid = false;
- List<AssertionConsumerService> allowedAssertionConsumerUrl = new MOAeIDASMetadataProviderDecorator(eIDASMetadataProvider)
- .getSPSSODescriptor(samlReq.getIssuer()).getAssertionConsumerServices();
+ boolean isValid = false;
+ List<AssertionConsumerService> allowedAssertionConsumerUrl =
+ MetadataUtil.getSPSSODescriptor(eIDASNodeEntityDesc).getAssertionConsumerServices();
for (AssertionConsumerService el : allowedAssertionConsumerUrl) {
if (reqAssertionConsumerServiceURL.equals(el.getLocation()))
@@ -229,13 +231,59 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController {
if (!isValid) {
Logger.info("eIDAS AuthnRequest contains a not valid 'AssertionConsumerServiceURL' attribute");
- throw new EIDASAuthnRequestValidationException("stork.01",
+ throw new EIDASAuthnRequestValidationException("eIDAS.12",
new Object[]{"eIDAS AuthnRequest contains a not valid 'AssertionConsumerServiceURL' attribute"});
}
- }
+ } else {
+ /*TODO: eIDAS SAMLEngine 1.1.0 does not validate and set AssertionConsumerServiceURL in a correct form
+ *
+ * Actually, this step is required because EidasProtocolProcesser.class only use the AssertionConsumerServiceURL
+ * from AuthnRequest to set the 'Destination' attribute in eIDAS Response. However, the AssertionConsumerServiceURL
+ * could be empty in Request, which break the Response building process.
+ */
+ String assertionConsumerServiceURL = MetadataUtil.getAssertionConsumerUrlFromMetadata(
+ SAMLEngineUtils.getMetadataFetcher(), SAMLEngineUtils.getMetadataSigner(), eIDASSamlReq);
+ if (MiscUtil.isEmpty(assertionConsumerServiceURL)) {
+ Logger.error("eIDAS metadata for node:" + eIDASSamlReq.getIssuer()
+ + " contains NO 'AssertionConsumerServiceURL' element!");
+ throw new EIDASSAMLEngineException("eIDAS metadata for node:" + eIDASSamlReq.getIssuer()
+ + " contains NO 'AssertionConsumerServiceURL' element!");
+
+ }
+
+ EidasAuthenticationRequest.Builder test = EidasAuthenticationRequest.builder(eIDASSamlReq);
+ test.assertionConsumerServiceURL(assertionConsumerServiceURL);
+ eIDASSamlReq = test.build();
+
+ }
+
+
+
+ //*************************************************
+ //***** store eIDAS request information *********
+ //*************************************************
+ // - memorize remote ip
+ pendingReq.setRemoteAddress(request.getRemoteAddr());
+
+ // - memorize relaystate
+ String relayState = request.getParameter("RelayState");
+ pendingReq.setRemoteRelayState(relayState);
+
+ // - memorize country code of target country
+ pendingReq.setGenericDataToSession(
+ RequestImpl.eIDAS_GENERIC_REQ_DATA_COUNTRY, samlReq.getOriginCountryCode());
+ //store level of assurance
+ pendingReq.setGenericDataToSession(RequestImpl.eIDAS_GENERIC_REQ_DATA_LEVELOFASSURENCE,
+ eIDASSamlReq.getEidasLevelOfAssurance().stringValue());
+ // - memorize requested attributes
+ pendingReq.setEidasRequestedAttributes(eIDASSamlReq.getRequestedAttributes());
+
+ // - memorize whole request
+ pendingReq.setEidasRequest(eIDASSamlReq);
+
// - memorize OA url
pendingReq.setOAURL(samlReq.getIssuer());
@@ -245,16 +293,19 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController {
throw new EIDASAuthnRequestProcessingException("eIDAS.08", new Object[]{pendingReq.getOAURL()});
pendingReq.setOnlineApplicationConfiguration(oaConfig);
-
- //TODO: is not supported any more ?!?
-// String spType = samlReq.getSPType();
-// if (MiscUtil.isEmpty(spType)) {
-// Logger.info("Load SPType from metadata ... IS NOT IMPLEMENTED YET!!!");
-// //TODO: maybe implement this if required
-//
-// }
-//
-// Logger.debug("eIDAS request has SPType:" + spType);
+
+ // - memorize service-provider type from eIDAS request
+ String spType = null;
+ if (eIDASSamlReq.getSpType() != null)
+ spType = eIDASSamlReq.getSpType().getValue();
+
+ if (MiscUtil.isEmpty(spType))
+ spType = MetadataUtil.getSPTypeFromMetadata(eIDASNodeEntityDesc);
+
+ if (MiscUtil.isEmpty(spType))
+ Logger.debug("eIDAS request has SPType:" + spType);
+ else
+ Logger.info("eIDAS request and eIDAS metadata contains NO 'SPType' element.");
} catch (MOAIDException e) {
Logger.info("eIDAS AuthnRequest preProcessing FAILED. Msg:" + e.getMessage());