From fd2752d6cb5a95aca7ed2206a9b8258942f17655 Mon Sep 17 00:00:00 2001 From: Thomas Knall Date: Mon, 23 Feb 2015 18:57:12 +0100 Subject: Improve Process Engine signal servlet (MOAID-73) - Update Process Engine signal servlet in order to allow module to provider their own strategy for providing the moa session id. - Update moa id handbook. - Update javadoc. --- .../stork/STORKProcessEngineSignalServlet.java | 113 +++++++++++++++++++++ .../stork/STORKWebApplicationInitializer.java | 48 --------- 2 files changed, 113 insertions(+), 48 deletions(-) create mode 100644 id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKProcessEngineSignalServlet.java delete mode 100644 id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKWebApplicationInitializer.java (limited to 'id/server/modules/module-stork/src/main/java/at') diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKProcessEngineSignalServlet.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKProcessEngineSignalServlet.java new file mode 100644 index 000000000..989f2b6bd --- /dev/null +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKProcessEngineSignalServlet.java @@ -0,0 +1,113 @@ +package at.gv.egovernment.moa.id.auth.modules.stork; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathFactory; + +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang3.StringUtils; +import org.bouncycastle.util.encoders.Base64; +import org.springframework.util.xml.SimpleNamespaceContext; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.auth.servlet.ProcessEngineSignalServlet; +import at.gv.egovernment.moa.logging.Logger; + +/** + * STORK module specific servlet, overloading {@link ProcessEngineSignalServlet}'s method + * {@linkplain ProcessEngineSignalServlet#getMoaSessionId(HttpServletRequest) getMoaSessionId(HttpServletRequest)} + * extending its capabilities for retrieving the current moa session id. + *

+ * This {@code STORKProcessEngineSignalServlet} tries to resolve the moa session id using the following strategy: + *

+ * + * @author tknall + * + */ +@WebServlet(urlPatterns = { "/PEPSConnectorWithLocalSigning", "/PEPSConnector" }, loadOnStartup = 1) +public class STORKProcessEngineSignalServlet extends ProcessEngineSignalServlet { + + private static final long serialVersionUID = 1L; + + public STORKProcessEngineSignalServlet() { + super(); + Logger.debug("Registering servlet " + getClass().getName() + " with mappings '/PEPSConnectorWithLocalSigning', '/PEPSConnector'."); + } + + @Override + public String getMoaSessionId(HttpServletRequest request) { + String sessionId = super.getMoaSessionId(request); + + try { + + // use SAML2 relayState + if (sessionId == null) { + sessionId = StringEscapeUtils.escapeHtml(request.getParameter("RelayState")); + } + + // take from InResponseTo attribute of SAMLResponse + if (sessionId == null) { + String base64SamlToken = request.getParameter("SAMLResponse"); + if (base64SamlToken != null) { + byte[] samlToken = Base64.decode(base64SamlToken); + Document samlResponse = parseDocument(new ByteArrayInputStream(samlToken)); + + XPath xPath = XPathFactory.newInstance().newXPath(); + SimpleNamespaceContext nsContext = new SimpleNamespaceContext(); + nsContext.bindNamespaceUri("saml2p", "urn:oasis:names:tc:SAML:2.0:protocol"); + xPath.setNamespaceContext(nsContext); + XPathExpression expression = xPath.compile("string(/saml2p:Response/@InResponseTo)"); + sessionId = (String) expression.evaluate(samlResponse, XPathConstants.STRING); + sessionId = StringEscapeUtils.escapeHtml(StringUtils.trimToNull(sessionId)); + } else { + Logger.warn("No parameter 'SAMLResponse'. Unable to retrieve MOA session id."); + } + } + + } catch (Exception e) { + Logger.warn("Unable to retrieve moa session id.", e); + } + + return sessionId; + } + + /** + * Parses a xml document (namespace aware). + * + * @param in + * The input stream. + * @return The DOM document. + * @throws ParserConfigurationException + * Thrown in case of configuration error. + * @throws IOException + * Thrown in case of error reading from the input stream. + * @throws SAXException + * Thrown in case of error parsing the document. + */ + public static Document parseDocument(InputStream in) throws ParserConfigurationException, SAXException, IOException { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setNamespaceAware(true); + documentBuilderFactory.setIgnoringElementContentWhitespace(false); + documentBuilderFactory.setValidating(false); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + return documentBuilder.parse(in); + } + +} diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKWebApplicationInitializer.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKWebApplicationInitializer.java deleted file mode 100644 index c54c9a26d..000000000 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKWebApplicationInitializer.java +++ /dev/null @@ -1,48 +0,0 @@ -package at.gv.egovernment.moa.id.auth.modules.stork; - -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.WebApplicationInitializer; - -import at.gv.egovernment.moa.id.auth.servlet.ProcessEngineSignalServlet; - -/** - * Spring automatically discovers {@link WebApplicationInitializer} implementations at startup.
- * This STORK webapp initializer adds the required servlet mappings: - * - * for the {@linkplain ProcessEngineSignalServlet process engine servlet} (named {@code ProcessEngineSignal}) that wakes - * up a process in order to execute asynchronous tasks. Therefore the servlet mappings mentioned above do not need to be - * declared in {@code web.xml}. - * - * @author tknall - * @see ProcessEngineSignalServlet - */ -public class STORKWebApplicationInitializer implements WebApplicationInitializer { - - private Logger log = LoggerFactory.getLogger(getClass()); - - private static final String SIGNAL_SERVLET_NAME = "ProcessEngineSignal"; - - private void addMapping(ServletRegistration servletRegistration, String mapping) { - log.debug("Adding mapping '{}' to servlet '{}' ({}).", mapping, SIGNAL_SERVLET_NAME, servletRegistration.getClassName()); - servletRegistration.addMapping(mapping); - } - - @Override - public void onStartup(ServletContext servletContext) throws ServletException { - ServletRegistration servletRegistration = servletContext.getServletRegistration(SIGNAL_SERVLET_NAME); - if (servletRegistration == null) { - throw new IllegalStateException("Servlet '" + SIGNAL_SERVLET_NAME + "' expected to be registered (e.g. by web.xml)."); - } - addMapping(servletRegistration, "/PEPSConnectorWithLocalSigning"); - addMapping(servletRegistration, "/PEPSConnector"); - } - -} -- cgit v1.2.3