Make WebSocket rejection less violent
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 13 Aug 2019 10:41:30 +0000 (12:41 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 13 Aug 2019 10:41:30 +0000 (12:41 +0200)
org.argeo.cms/src/org/argeo/cms/websocket/CmsWebSocketConfigurator.java
org.argeo.ext.equinox.jetty/src/org/argeo/equinox/jetty/WebSocketJettyCustomizer.java

index cd435aa43a0e5a2b5fb715b417399de590195f09..7cfe5748b19a7af3c51bc452f05c53d84f7c6096 100644 (file)
@@ -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<String> 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<String> lst = new ArrayList<String>();
+               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");
        }
 }
index 31d62c80be22ea61c337a5dfa0d6bebf18792b5b..f582a43bc404810c6a64ba4e7e60edc03a6f52a7 100644 (file)
@@ -18,38 +18,6 @@ public class WebSocketJettyCustomizer extends JettyCustomizer {
        public Object customizeContext(Object context, Dictionary<String, ?> 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<String> 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<HttpCookie> 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<ServerEndpointConfig.Builder, ServerEndpointConfig.Builder> endpointsTracker = new ServiceTracker<ServerEndpointConfig.Builder, ServerEndpointConfig.Builder>(
-//                                     bc, ServerEndpointConfig.Builder.class, null) {
-//
-//                             @Override
-//                             public ServerEndpointConfig.Builder addingService(
-//                                             ServiceReference<ServerEndpointConfig.Builder> 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<ServiceReference<CmsSession>> 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;
-//             }
-//     }
-
 }