From 1fe0dfe4e142ddffbd42c8b58ac6163e47d73f7d Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Mon, 7 Dec 2020 09:52:08 +0100 Subject: add eIDAS MS Proxy-Service simulator into demo OA --- .../egovernment/moa/id/demoOA/Configuration.java | 5 ++ .../moa/id/demoOA/servlet/pvp2/Authenticate.java | 73 +++++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java index d6c14fd07..07edb250d 100644 --- a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java @@ -196,6 +196,11 @@ public class Configuration { return props.getProperty("general.login.pvp2.sp.requesterId"); } + public boolean isEidasProxySimulatorEnabled() { + return Boolean.parseBoolean( + props.getProperty("general.login.pvp2.sp.eidas.proxy.simulation", "false")); + } + public boolean setNameIdPolicy() { return Boolean.parseBoolean(props.getProperty("general.login.pvp2.req.set.nameIDPolicy", "true")); } diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Authenticate.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Authenticate.java index 4e8e12499..d4c67cfae 100644 --- a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Authenticate.java +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Authenticate.java @@ -23,7 +23,9 @@ package at.gv.egovernment.moa.id.demoOA.servlet.pvp2; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.security.KeyStore; +import java.text.MessageFormat; import java.util.Map; import javax.servlet.ServletException; @@ -34,6 +36,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomUtils; import org.apache.commons.lang3.StringUtils; import org.apache.velocity.app.VelocityEngine; @@ -45,6 +48,7 @@ import org.opensaml.common.impl.SecureRandomIdentifierGenerator; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.binding.encoding.HTTPPostEncoder; import org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoder; +import org.opensaml.saml2.common.Extensions; import org.opensaml.saml2.core.AuthnContextClassRef; import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration; import org.opensaml.saml2.core.AuthnRequest; @@ -60,13 +64,25 @@ import org.opensaml.saml2.metadata.SingleSignOnService; import org.opensaml.saml2.metadata.impl.SingleSignOnServiceBuilder; import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider; import org.opensaml.ws.transport.http.HttpServletResponseAdapter; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.io.Marshaller; +import org.opensaml.xml.io.MarshallingException; +import org.opensaml.xml.io.Unmarshaller; +import org.opensaml.xml.io.UnmarshallingException; +import org.opensaml.xml.schema.XSAny; import org.opensaml.xml.security.x509.KeyStoreX509CredentialAdapter; import org.opensaml.xml.security.x509.X509Credential; import org.opensaml.xml.signature.Signature; import org.opensaml.xml.signature.SignatureConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; +import at.gv.egiz.eaaf.core.api.data.EAAFConstants; +import at.gv.egiz.eaaf.core.impl.utils.DOMUtils; +import at.gv.egiz.eaaf.core.impl.utils.EAAFDomEntityResolver; import at.gv.egovernment.moa.id.demoOA.Configuration; import at.gv.egovernment.moa.id.demoOA.exception.ConfigurationException; import at.gv.egovernment.moa.id.demoOA.utils.SAML2Utils; @@ -215,6 +231,11 @@ public class Authenticate extends HttpServlet { } + if (config.isEidasProxySimulatorEnabled()) { + authReq = injectEidasMsProxyAttributes(request, authReq); + + } + //sign authentication request KeyStore keyStore = config.getPVP2KeyStore(); @@ -284,7 +305,57 @@ public class Authenticate extends HttpServlet { } } - /** + + private AuthnRequest injectEidasMsProxyAttributes(HttpServletRequest request, AuthnRequest authReq) + throws SAXException, IOException, ParserConfigurationException, MarshallingException, UnmarshallingException { + + //build extension from template + String xmlTemplate = IOUtils.toString( + Authenticate.class.getResourceAsStream("/templates/reqAttributes.xml"), + StandardCharsets.UTF_8); + + String target = EAAFConstants.URN_PREFIX_EIDAS + "AT+" + getParameterOrDefault(request, "eidasCountry", "DE"); + String loa = EAAFConstants.EIDAS_LOA_PREFIX + getParameterOrDefault(request, "loa", "high"); + String eidasConnector = "https://simple.test/" + getParameterOrDefault(request, "eidasIdPostfix", "test"); + String xmlString = MessageFormat.format(xmlTemplate, target, loa, eidasConnector); + log.debug("Formated requested attributes: " + xmlString); + + Document extension = DOMUtils.parseDocument(xmlString, false, null, null); + + + //marshalle, inject, and unmarshalle request to set extension + //TODO: find better solution, be it is good enough for a first simple test + DocumentBuilder builder; + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + builder = factory.newDocumentBuilder(); + Document document = builder.newDocument(); + Marshaller out = org.opensaml.Configuration.getMarshallerFactory().getMarshaller(authReq); + out.marshall(authReq, document); + + Node extElement = document.importNode(extension.getDocumentElement(), true); + //document.getDocumentElement().appendChild(extElement); + document.getDocumentElement().insertBefore(extElement, document.getChildNodes().item(2)); + + Unmarshaller in = org.opensaml.Configuration.getUnmarshallerFactory().getUnmarshaller(document.getDocumentElement()); + return (AuthnRequest) in.unmarshall(document.getDocumentElement()); + + } + + + private String getParameterOrDefault(HttpServletRequest request, String paramName, String defaultValue) { + String reqParam = request.getParameter(paramName); + if (MiscUtil.isEmpty(reqParam)) { + return defaultValue; + + } else { + return reqParam; + + } + + } + + + /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ -- cgit v1.2.3