aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java')
-rw-r--r--id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java229
1 files changed, 175 insertions, 54 deletions
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 9943cc5fb..0f17eccab 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
@@ -23,8 +23,8 @@
package at.gv.egovernment.moa.id.protocols.eidas;
import java.io.StringWriter;
+import java.security.MessageDigest;
import java.text.SimpleDateFormat;
-import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -32,29 +32,44 @@ 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;
+import com.google.common.collect.ImmutableSet;
+
import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;
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.utils.MOAPersonalAttributeList;
-import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils;
+import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SimpleEidasAttributeGenerator;
import at.gv.egovernment.moa.id.commons.api.IRequest;
import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException;
import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.SLOInformationImpl;
import at.gv.egovernment.moa.id.data.SLOInformationInterface;
import at.gv.egovernment.moa.id.moduls.IAction;
+import at.gv.egovernment.moa.id.protocols.builder.attributes.IAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.builder.attributes.MandateLegalPersonFullNameAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.builder.attributes.MandateLegalPersonSourcePinAttributeBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
+import at.gv.egovernment.moa.id.util.Random;
import at.gv.egovernment.moa.logging.Logger;
-import eu.eidas.auth.commons.EIDASAuthnResponse;
-import eu.eidas.auth.commons.EIDASStatusCode;
-import eu.eidas.auth.commons.EIDASUtil;
-import eu.eidas.auth.commons.PersonalAttribute;
-import eu.eidas.auth.engine.EIDASSAMLEngine;
-import eu.eidas.auth.engine.metadata.MetadataUtil;
+import at.gv.egovernment.moa.util.Base64Utils;
+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;
+import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
+import eu.eidas.auth.commons.protocol.IResponseMessage;
+import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse;
+import eu.eidas.auth.commons.protocol.impl.SamlNameIdFormat;
+import eu.eidas.auth.engine.ProtocolEngineI;
+import eu.eidas.auth.engine.xml.opensaml.SAMLEngineUtils;
/**
@@ -67,7 +82,10 @@ import eu.eidas.auth.engine.metadata.MetadataUtil;
@Service("eIDASAuthenticationRequest")
public class eIDASAuthenticationRequest implements IAction {
+ private static IAttributeGenerator<String> generator = new SimpleEidasAttributeGenerator();
+
@Autowired protected MOAReversionLogger revisionsLogger;
+ @Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider;
@Override
public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException {
@@ -78,67 +96,136 @@ public class eIDASAuthenticationRequest implements IAction {
throw new MOAIDException("got wrong IRequest type. is: {}, should be: {}", new String[] {req.getClass().toString(), EIDASData.class.toString()});
- // gather attributes
- MOAPersonalAttributeList resultingAttributeList = (MOAPersonalAttributeList) eidasRequest.getEidasRequestedAttributes().clone();
+ String subjectNameID = null;
- for(Entry<String, PersonalAttribute> current : resultingAttributeList.entrySet()) {
+ //gather attributes
+ ImmutableAttributeMap reqAttributeList = (ImmutableAttributeMap) eidasRequest.getEidasRequestedAttributes();
+ ImmutableAttributeMap.Builder attrMapBuilder = ImmutableAttributeMap.builder();
+
+ //TODO: if we support more then this minimum required attributes -> redesign to a smoother attribute builder selector
+ for(AttributeDefinition<?> attr : reqAttributeList.getDefinitions()) {
String newValue = "";
-
- // TODO make use of proper builder
- switch(current.getKey()) {
- 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;
-
- //TODO: change bPK builder !!!!!!
- case Constants.eIDAS_ATTR_PERSONALIDENTIFIER: newValue = authData.getBPK(); break;
+ boolean isUniqueID = false;
+ try {
+ 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();
+ isUniqueID = true;
+
+ //generate a transient unique identifier if it is requested
+ String reqNameIDFormat = eidasRequest.getEidasRequest().getNameIdFormat();
+ if (MiscUtil.isNotEmpty(reqNameIDFormat)
+ && reqNameIDFormat.equals(SamlNameIdFormat.TRANSIENT.getNameIdFormat()))
+ newValue = generateTransientNameID(newValue);
+
+ subjectNameID = newValue;
+ break;
+ case Constants.eIDAS_ATTR_LEGALPERSONIDENTIFIER:
+ newValue = new MandateLegalPersonSourcePinAttributeBuilder().build(
+ req.getOnlineApplicationConfiguration(), authData, generator);
+ break;
+ case Constants.eIDAS_ATTR_LEGALNAME:
+ newValue = new MandateLegalPersonFullNameAttributeBuilder().build(
+ req.getOnlineApplicationConfiguration(), authData, generator);
+ break;
+
+ }
+
+ } catch (AttributeException e) {
+ Logger.debug("Attribute can not generate requested attribute:" + attr.getFriendlyName() + " Reason:" + e.getMessage());
+
}
-
- if("".equals(newValue))
- current.getValue().setStatus(EIDASStatusCode.STATUS_NOT_AVAILABLE.toString());
- else {
- current.getValue().getValue().clear();
- current.getValue().getValue().add(newValue);
- current.getValue().setStatus(EIDASStatusCode.STATUS_AVAILABLE.toString());
+
+ if(MiscUtil.isEmpty(newValue)) {
+ Logger.info("eIDAS Attr:" + attr.getNameUri() + " is not available.");
+
+ } else {
+ //set uniqueIdentifier attribute, because eIDAS SAMLEngine use this flag to select the
+ // Subject->NameID value from this attribute
+ Builder<?> attrBuilder = AttributeDefinition.builder(attr);
+ attrBuilder.uniqueIdentifier(isUniqueID);
+ AttributeDefinition<?> returnAttr = attrBuilder.build();
+
+ //unmarshal attribute value into eIDAS attribute
+ 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);
+
+ }
+
+ //add attribute to Map
+ attrMapBuilder.put((AttributeDefinition)returnAttr, (ImmutableSet) builder.build());
+
}
}
// construct eIDaS response
- EIDASAuthnResponse response = new EIDASAuthnResponse();
- response.setPersonalAttributeList(resultingAttributeList);
+ AuthenticationResponse.Builder responseBuilder = new AuthenticationResponse.Builder();
+
+ responseBuilder.id(SAMLEngineUtils.generateNCName());
+ responseBuilder.inResponseTo(eidasRequest.getEidasRequest().getId());
- // - create metadata url
- String pubURLPrefix = req.getAuthURL();
+ String pubURLPrefix = req.getAuthURL();
String metadata_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_METADATA;
- response.setIssuer(metadata_url);
-
- response.setAssuranceLevel(authData.getEIDASQAALevel());
+ responseBuilder.issuer(metadata_url);
+
+ responseBuilder.levelOfAssurance(authData.getEIDASQAALevel());
+
+ //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 {
- EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine();
+ ProtocolEngineI engine = at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider);
// encryption is done by the SamlEngine, i.e. by the module we provide in the config
// but we need to set the appropriate request issuer
- engine.setRequestIssuer(eidasRequest.getEidasRequest().getIssuer());
-
+ //engine.setRequestIssuer(eidasRequest.getEidasRequest().getIssuer());
- if(null == eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()) {
- String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata(
- new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()),
- engine,
- eidasRequest.getEidasRequest());
- eidasRequest.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl);
-
- }
+ eIDASRespMsg = engine.generateResponseMessage(eidasRequest.getEidasRequest(),
+ response, true, eidasRequest.getRemoteAddress());
+
+// if(null == eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()) {
+// String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata(
+// new MOAeIDASMetadataProviderDecorator(eIDASMetadataProvider),
+// engine,
+// eidasRequest.getEidasRequest());
+// eidasRequest.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl);
+//
+// }
- response = engine.generateEIDASAuthnResponse(eidasRequest.getEidasRequest(), response, eidasRequest.getRemoteAddress(), true);
+// response = engine.generateEIDASAuthnResponse(eidasRequest.getEidasRequest(), response, eidasRequest.getRemoteAddress(), true);
- token = EIDASUtil.encodeSAMLToken(response.getTokenSaml());
+ token = EidasStringUtil.encodeToBase64(eIDASRespMsg.getMessageBytes());
+
+ } catch(Exception e) {
+ Logger.error("eIDAS Response encoding error." , e);
+ throw new MOAIDException("eIDAS.13", new Object[]{e.getMessage()}, e);
- } catch(Exception e) {
- e.printStackTrace();
}
revisionsLogger.logEvent(req, Constants.eIDAS_REVERSIONSLOG_IDP_AUTHREQUEST);
@@ -169,10 +256,28 @@ 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;
+
+ SLOInformationInterface ssoContainer = null;
+ try {
+ ssoContainer = new SLOInformationImpl(
+ req.getAuthURL(),
+ eidasRequest.getEidasRequest().getIssuer(),
+ null,
+ subjectNameID,
+ eidasRequest.getEidasRequest().getNameIdFormat(),
+ EIDASProtocol.NAME);
+
+ } catch (Exception e) {
+ Logger.error("Can not generate container with SSO information!", e);
+
+ }
+
+ return ssoContainer;
+
}
@Override
@@ -186,4 +291,20 @@ public class eIDASAuthenticationRequest implements IAction {
}
+ private String generateTransientNameID(String nameID) {
+ String random = Random.nextLongRandom();
+
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+ byte[] hash = md.digest((nameID + random).getBytes("ISO-8859-1"));
+ return Base64Utils.encode(hash);
+
+ } catch (Exception e) {
+ Logger.error("Can not generate transient personal identifier!", e);
+ return null;
+
+ }
+
+ }
+
}