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-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
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')
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java135
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java8
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java57
3 files changed, 138 insertions, 62 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());
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 a93dff3b3..dcce442a0 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
@@ -31,7 +31,9 @@ import org.springframework.stereotype.Service;
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.exceptions.EIDASEngineException;
+import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAeIDASMetadataGenerator;
import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils;
+import at.gv.egovernment.moa.id.commons.api.AuthConfiguration;
import at.gv.egovernment.moa.id.commons.api.IRequest;
import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException;
import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException;
@@ -43,7 +45,6 @@ import at.gv.egovernment.moa.logging.Logger;
import eu.eidas.auth.engine.ProtocolEngineI;
import eu.eidas.auth.engine.metadata.Contact;
import eu.eidas.auth.engine.metadata.MetadataConfigParams;
-import eu.eidas.auth.engine.metadata.MetadataGenerator;
import eu.eidas.engine.exceptions.EIDASSAMLEngineException;
@@ -54,6 +55,7 @@ import eu.eidas.engine.exceptions.EIDASSAMLEngineException;
public class EidasMetaDataRequest implements IAction {
@Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider;
+ @Autowired(required=true) AuthConfiguration authConfig;
/* (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.data.IAuthData)
@@ -110,7 +112,7 @@ public class EidasMetaDataRequest implements IAction {
ProtocolEngineI engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider);
- MetadataGenerator generator = new MetadataGenerator();
+ MOAeIDASMetadataGenerator generator = new MOAeIDASMetadataGenerator();
MetadataConfigParams mcp=new MetadataConfigParams();
generator.setConfigParams(mcp);
generator.initialize(engine);
@@ -158,7 +160,7 @@ public class EidasMetaDataRequest implements IAction {
if (pvpOrganisation != null) {
mcp.setNodeUrl(pvpOrganisation.getURLs().get(0).getURL().getLocalString());
- mcp.setCountryName("Austria");
+ mcp.setCountryName(authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRY, "Austria"));
technicalContact.setCompany(pvpOrganisation.getDisplayNames().get(0).getName().getLocalString());
}
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 9e29c01f3..168cb42d9 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
@@ -31,6 +31,7 @@ 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.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
@@ -50,6 +51,7 @@ import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.MiscUtil;
import eu.eidas.auth.commons.EidasStringUtil;
import eu.eidas.auth.commons.attribute.AttributeDefinition;
+import eu.eidas.auth.commons.attribute.AttributeDefinition.Builder;
import eu.eidas.auth.commons.attribute.AttributeValue;
import eu.eidas.auth.commons.attribute.AttributeValueMarshaller;
import eu.eidas.auth.commons.attribute.AttributeValueMarshallingException;
@@ -89,36 +91,48 @@ public class eIDASAuthenticationRequest implements IAction {
for(AttributeDefinition<?> attr : reqAttributeList.getDefinitions()) {
String newValue = "";
-
+ boolean isUniqueID = false;
// TODO make use of proper builder
+
switch(attr.getFriendlyName()) {
- case Constants.eIDAS_ATTR_DATEOFBIRTH: newValue = new SimpleDateFormat("YYYY-MM-dd").format(authData.getDateOfBirth()); break;
- case Constants.eIDAS_ATTR_CURRENTFAMILYNAME: newValue = authData.getFamilyName();break;
- case Constants.eIDAS_ATTR_CURRENTGIVENNAME: newValue = authData.getGivenName();break;
- case Constants.eIDAS_ATTR_PERSONALIDENTIFIER: newValue = authData.getBPK(); break;
+ case Constants.eIDAS_ATTR_DATEOFBIRTH:
+ newValue = new SimpleDateFormat("YYYY-MM-dd").format(authData.getDateOfBirth());
+ break;
+ case Constants.eIDAS_ATTR_CURRENTFAMILYNAME:
+ newValue = authData.getFamilyName();
+ break;
+ case Constants.eIDAS_ATTR_CURRENTGIVENNAME:
+ newValue = authData.getGivenName();
+ break;
+ case Constants.eIDAS_ATTR_PERSONALIDENTIFIER:
+ newValue = authData.getBPK();
+ isUniqueID = true;
+ break;
}
-
+
if(MiscUtil.isEmpty(newValue)) {
-// current.getValue().setStatus(EIDASStatusCode.STATUS_NOT_AVAILABLE.toString());
Logger.info("eIDAS Attr:" + attr.getNameUri() + " is not available.");
} else {
- AttributeValueMarshaller<?> attributeValueMarshaller = attr.getAttributeValueMarshaller();
- ImmutableSet.Builder<AttributeValue<?>> builder = ImmutableSet.builder();
+ Builder<?> attrBuilder = AttributeDefinition.builder(attr);
+ attrBuilder.uniqueIdentifier(isUniqueID);
+ AttributeDefinition<?> returnAttr = attrBuilder.build();
+ AttributeValueMarshaller<?> attributeValueMarshaller = returnAttr.getAttributeValueMarshaller();
+ ImmutableSet.Builder<AttributeValue<?>> builder = ImmutableSet.builder();
+
AttributeValue<?> attributeValue = null;
try {
attributeValue = attributeValueMarshaller.unmarshal(newValue, false);
+ builder.add(attributeValue);
} catch (AttributeValueMarshallingException e) {
throw new IllegalStateException(e);
}
-
- //TODO: check for 'isAvailable flag'!
- attrMapBuilder.put((AttributeDefinition)attr, (ImmutableSet) builder.build());
+ attrMapBuilder.put((AttributeDefinition)returnAttr, (ImmutableSet) builder.build());
}
@@ -141,10 +155,16 @@ public class eIDASAuthenticationRequest implements IAction {
//add attributes
responseBuilder.attributes(attrMapBuilder.build());
+ //set success statuscode
+ responseBuilder.statusCode(StatusCode.SUCCESS_URI);
+
+
+
//build response
AuthenticationResponse response = responseBuilder.build();
String token = null;
+ IResponseMessage eIDASRespMsg = null;
try {
ProtocolEngineI engine = at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider);
@@ -152,9 +172,9 @@ public class eIDASAuthenticationRequest implements IAction {
// but we need to set the appropriate request issuer
//engine.setRequestIssuer(eidasRequest.getEidasRequest().getIssuer());
- IResponseMessage eIDASRespMsg = engine.generateResponseMessage(eidasRequest.getEidasRequest(),
+ eIDASRespMsg = engine.generateResponseMessage(eidasRequest.getEidasRequest(),
response, true, eidasRequest.getRemoteAddress());
-
+
// if(null == eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()) {
// String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata(
// new MOAeIDASMetadataProviderDecorator(eIDASMetadataProvider),
@@ -169,8 +189,9 @@ public class eIDASAuthenticationRequest implements IAction {
token = EidasStringUtil.encodeToBase64(eIDASRespMsg.getMessageBytes());
- } catch(Exception e) {
- e.printStackTrace();
+ } catch(Exception e) {
+ Logger.error("eIDAS Response encoding error." , e);
+ throw new MOAIDException("eIDAS.13", new Object[]{e.getMessage()}, e);
}
@@ -202,7 +223,9 @@ public class eIDASAuthenticationRequest implements IAction {
httpResp.setContentType(MediaType.TEXT_HTML.getType());
} catch (Exception e) {
- Logger.error("Velocity error: " + e.getMessage());
+ Logger.error("Velocity error: " + e.getMessage());
+ throw new MOAIDException("eIDAS.13", new Object[]{e.getMessage()}, e);
+
}
return null;