From 862da18b7053df010348b3ed1096afd3b5778c10 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Tue, 13 Aug 2019 12:41:30 +0200 Subject: [PATCH] Make WebSocket rejection less violent --- .../websocket/CmsWebSocketConfigurator.java | 21 ++-- .../jetty/WebSocketJettyCustomizer.java | 106 ++---------------- 2 files changed, 19 insertions(+), 108 deletions(-) diff --git a/org.argeo.cms/src/org/argeo/cms/websocket/CmsWebSocketConfigurator.java b/org.argeo.cms/src/org/argeo/cms/websocket/CmsWebSocketConfigurator.java index cd435aa43..7cfe5748b 100644 --- a/org.argeo.cms/src/org/argeo/cms/websocket/CmsWebSocketConfigurator.java +++ b/org.argeo.cms/src/org/argeo/cms/websocket/CmsWebSocketConfigurator.java @@ -1,5 +1,6 @@ package org.argeo.cms.websocket; +import java.util.ArrayList; import java.util.List; import javax.security.auth.login.LoginContext; @@ -16,7 +17,7 @@ import org.apache.commons.logging.LogFactory; import org.argeo.cms.auth.HttpRequestCallbackHandler; import org.argeo.node.NodeConstants; -public final class CmsWebSocketConfigurator extends Configurator { +public class CmsWebSocketConfigurator extends Configurator { private final static Log log = LogFactory.getLog(CmsWebSocketConfigurator.class); final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate"; @@ -62,6 +63,7 @@ public final class CmsWebSocketConfigurator extends Configurator { if (httpSession == null) { rejectResponse(response); + return; } try { LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, @@ -72,20 +74,17 @@ public final class CmsWebSocketConfigurator extends Configurator { sec.getUserProperties().put("subject", lc.getSubject()); } catch (LoginException e) { rejectResponse(response); + return; } - -// List authHeaders = request.getHeaders().get(HEADER_WWW_AUTHENTICATE); -// String authHeader; -// if (authHeaders != null && authHeaders.size() == 1) { -// authHeader = authHeaders.get(0); -// } else { -// return; -// } } - private void rejectResponse(HandshakeResponse response) { + protected void rejectResponse(HandshakeResponse response) { + List lst = new ArrayList(); + lst.add("no"); + response.getHeaders().put(HandshakeResponse.SEC_WEBSOCKET_ACCEPT, lst); + // violent implementation, as suggested in // https://stackoverflow.com/questions/21763829/jsr-356-how-to-abort-a-websocket-connection-during-the-handshake - throw new IllegalStateException("Web socket cannot be authenticated"); + // throw new IllegalStateException("Web socket cannot be authenticated"); } } 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 31d62c80b..f582a43bc 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 @@ -18,38 +18,6 @@ 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); } @@ -73,6 +41,15 @@ public class WebSocketJettyCustomizer extends JettyCustomizer { // public void onSessionOpened(WebSocketSession session) { // UpgradeRequest upgradeRequest = session.getUpgradeRequest(); // UpgradeResponse upgradeResponse = session.getUpgradeResponse(); +// List acceptHeader = upgradeResponse.getHeaders("Sec-WebSocket-Accept"); +// if (acceptHeader.contains("no")) +// try { +// upgradeResponse.sendForbidden("FORBIDDEN"); +// return; +// } catch (IOException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } // List cookies = upgradeRequest.getCookies(); // // System.out.println("Upgrade request cookies : " + cookies); @@ -102,82 +79,17 @@ public class WebSocketJettyCustomizer extends JettyCustomizer { // 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); } bc.registerService(javax.websocket.server.ServerContainer.class, serverContainer, null); -// ServiceTracker endpointsTracker = new ServiceTracker( -// bc, ServerEndpointConfig.Builder.class, null) { -// -// @Override -// public ServerEndpointConfig.Builder addingService( -// ServiceReference reference) { -// -// ServerEndpointConfig.Builder serverEndpointConfig = super.addingService(reference); -// try { -// serverContainer.addEndpoint(serverEndpointConfig.build()); -// } catch (DeploymentException e) { -// throw new IllegalArgumentException("Cannot add end point " + reference, e); -// } -// return serverEndpointConfig; -// } -// }; -// endpointsTracker.open(); - // TODO log it properly - // TODO close itproperly } } - -// 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; -// } -// } - } -- 2.30.2