From: Mathieu Baudier Date: Thu, 9 May 2019 07:49:51 +0000 (+0200) Subject: Integrate web sockets with CMS session X-Git-Tag: argeo-commons-2.1.77~4 X-Git-Url: https://git.argeo.org/?a=commitdiff_plain;h=8d69d13b486f10aed4aeb37ed8617a908ce98f5f;p=lgpl%2Fargeo-commons.git Integrate web sockets with CMS session --- diff --git a/org.argeo.ext.equinox.jetty/bnd.bnd b/org.argeo.ext.equinox.jetty/bnd.bnd index 8b1b7146d..0f21e73c9 100644 --- a/org.argeo.ext.equinox.jetty/bnd.bnd +++ b/org.argeo.ext.equinox.jetty/bnd.bnd @@ -3,4 +3,5 @@ Fragment-Host: org.eclipse.equinox.http.jetty Import-Package: org.eclipse.jetty.websocket.jsr356,\ org.eclipse.jetty.websocket.api,\ org.eclipse.jetty.websocket.common,\ +org.osgi.service.http,\ * \ No newline at end of file diff --git a/org.argeo.ext.equinox.jetty/pom.xml b/org.argeo.ext.equinox.jetty/pom.xml index 2c71d6f61..491c5e558 100644 --- a/org.argeo.ext.equinox.jetty/pom.xml +++ b/org.argeo.ext.equinox.jetty/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 org.argeo.commons @@ -9,4 +11,11 @@ org.argeo.ext.equinox.jetty Extension of Equinox Jetty Integration + + + org.argeo.commons + org.argeo.cms + 2.1.77-SNAPSHOT + + \ No newline at end of file diff --git a/org.argeo.ext.equinox.jetty/src/org/argeo/equinox/jetty/WebSocketJettyCustomizer.java b/org.argeo.ext.equinox.jetty/src/org/argeo/equinox/jetty/WebSocketJettyCustomizer.java index e59bbc012..83934537c 100644 --- a/org.argeo.ext.equinox.jetty/src/org/argeo/equinox/jetty/WebSocketJettyCustomizer.java +++ b/org.argeo.ext.equinox.jetty/src/org/argeo/equinox/jetty/WebSocketJettyCustomizer.java @@ -1,21 +1,29 @@ package org.argeo.equinox.jetty; import java.net.HttpCookie; +import java.util.Collection; import java.util.Dictionary; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpSession; +import org.argeo.cms.auth.CmsSession; import org.eclipse.equinox.http.jetty.JettyCustomizer; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.websocket.api.UpgradeRequest; +import org.eclipse.jetty.websocket.api.UpgradeResponse; import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.WebSocketSessionListener; +import org.eclipse.jetty.websocket.jsr356.JsrSession; import org.eclipse.jetty.websocket.jsr356.server.ServerContainer; import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.osgi.service.http.HttpContext; +import org.osgi.service.useradmin.Authorization; public class WebSocketJettyCustomizer extends JettyCustomizer { private BundleContext bc = FrameworkUtil.getBundle(WebSocketJettyCustomizer.class).getBundleContext(); @@ -24,6 +32,38 @@ public class WebSocketJettyCustomizer extends JettyCustomizer { public Object customizeContext(Object context, Dictionary settings) { ServletContextHandler servletContextHandler = (ServletContextHandler) context; new WebSocketInit(servletContextHandler).start(); +// servletContextHandler.addFilter(new FilterHolder(new Filter() { +// +// @Override +// public void init(FilterConfig filterConfig) throws ServletException { +// // TODO Auto-generated method stub +// +// } +// +// @Override +// public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) +// throws IOException, ServletException { +// HttpServletRequest httpRequest = (HttpServletRequest) request; +// HttpServletResponse httpResponse = (HttpServletResponse) response; +// +// HttpRequestCallbackHandler callbackHandler = new HttpRequestCallbackHandler(httpRequest, httpResponse); +// try { +// LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, callbackHandler); +// lc.login(); +// +// chain.doFilter(httpRequest, httpResponse); +// } catch (LoginException e) { +// httpResponse.setStatus(403); +// } +// +// } +// +// @Override +// public void destroy() { +// // TODO Auto-generated method stub +// +// } +// }), "/vje/events", EnumSet.of(DispatcherType.REQUEST)); return super.customizeContext(context, settings); } @@ -41,23 +81,69 @@ public class WebSocketJettyCustomizer extends JettyCustomizer { ServerContainer serverContainer; try { serverContainer = WebSocketServerContainerInitializer.configureContext(servletContextHandler); -// serverContainer.addSessionListener(new WebSocketSessionListener() { -// -// @Override -// public void onSessionOpened(WebSocketSession session) { -// UpgradeRequest upgradeRequest = session.getUpgradeRequest(); -// List cookies = upgradeRequest.getCookies(); -// System.out.println("Upgrade request cookies : " + cookies); -// HttpSession httpSession = (HttpSession) upgradeRequest.getSession(); -// System.out.println("Upgrade request session ID : " + httpSession.getId()); -// } -// -// @Override -// public void onSessionClosed(WebSocketSession session) { -// // TODO Auto-generated method stub -// -// } -// }); + serverContainer.addSessionListener(new WebSocketSessionListener() { + + @Override + public void onSessionOpened(WebSocketSession session) { + UpgradeRequest upgradeRequest = session.getUpgradeRequest(); + UpgradeResponse upgradeResponse = session.getUpgradeResponse(); + List cookies = upgradeRequest.getCookies(); + + System.out.println("Upgrade request cookies : " + cookies); + String httpSessionId = null; + if (cookies != null) { + for (HttpCookie cookie : cookies) { + if (cookie.getName().equals("JSESSIONID")) { + httpSessionId = cookie.getValue(); + } + } + } + + if (httpSessionId == null) { + HttpSession httpSession = (HttpSession) upgradeRequest.getSession(); + if (httpSession == null) { +// session.disconnect(); +// return; + } else { + httpSessionId = httpSession.getId(); + System.out.println("Upgrade request session ID : " + httpSession.getId()); + } + } + + if (httpSessionId != null) { + int dotIdx = httpSessionId.lastIndexOf('.'); + if (dotIdx > 0) { + httpSessionId = httpSessionId.substring(0, dotIdx); + } + } + + CmsSession cmsSession = getCmsSession(httpSessionId); + if (cmsSession == null) { + session.disconnect(); + return; +// try { +// session.getUpgradeResponse().sendForbidden("Web Sockets must always be authenticated."); +// } catch (IOException e) { +// e.printStackTrace(); +// } + } else { + JsrSession jsrSession = (JsrSession) session; + String jsrId = jsrSession.getId(); + System.out.println("JSR ID: " + jsrId); + jsrSession.getUserProperties().put(CmsSession.SESSION_LOCAL_ID, cmsSession.getLocalId()); + jsrSession.getUserProperties().put(CmsSession.SESSION_UUID, cmsSession.getUuid()); + jsrSession.getUserProperties().put(HttpContext.REMOTE_USER, cmsSession.getUserDn()); + // httpSession.setAttribute(HttpContext.AUTHORIZATION, + // cmsSession.getAuthorization()); + } + } + + @Override + public void onSessionClosed(WebSocketSession session) { + // TODO Auto-generated method stub + + } + }); } catch (ServletException e) { throw new IllegalStateException("Cannot configure web sockets", e); } @@ -85,4 +171,26 @@ public class WebSocketJettyCustomizer extends JettyCustomizer { } + private CmsSession getCmsSession(String httpSessionId) { + if (httpSessionId == null) + return null; + + Collection> sr; + try { + sr = bc.getServiceReferences(CmsSession.class, + "(" + CmsSession.SESSION_LOCAL_ID + "=" + httpSessionId + ")"); + } catch (InvalidSyntaxException e) { + throw new IllegalStateException("Cannot get CMS session for id " + httpSessionId, e); + } + if (sr.size() == 1) { + CmsSession cmsSession = bc.getService(sr.iterator().next()); + Authorization authorization = cmsSession.getAuthorization(); + if (authorization.getName() == null) + return null;// anonymous is not sufficient + return cmsSession; + } else { + return null; + } + } + }