]> git.argeo.org Git - lgpl/argeo-commons.git/blob - eclipse/org.argeo.cms.servlet/src/org/argeo/cms/websocket/javax/server/CmsWebSocketConfigurator.java
Reintroduce web socket support.
[lgpl/argeo-commons.git] / eclipse / org.argeo.cms.servlet / src / org / argeo / cms / websocket / javax / server / CmsWebSocketConfigurator.java
1 package org.argeo.cms.websocket.javax.server;
2
3 import java.security.AccessController;
4 import java.security.PrivilegedAction;
5 import java.util.List;
6
7 import javax.security.auth.Subject;
8 import javax.security.auth.login.LoginContext;
9 import javax.websocket.Extension;
10 import javax.websocket.HandshakeResponse;
11 import javax.websocket.server.HandshakeRequest;
12 import javax.websocket.server.ServerEndpointConfig;
13 import javax.websocket.server.ServerEndpointConfig.Configurator;
14
15 import org.argeo.api.cms.CmsAuth;
16 import org.argeo.api.cms.CmsLog;
17 import org.argeo.cms.auth.RemoteAuthCallbackHandler;
18 import org.argeo.cms.auth.RemoteAuthSession;
19 import org.argeo.cms.servlet.ServletHttpSession;
20 import org.osgi.service.http.context.ServletContextHelper;
21
22 /**
23 * <strong>Disabled until third party issues are solved.</strong>. Customises
24 * the initialisation of a new web socket.
25 */
26 public class CmsWebSocketConfigurator extends Configurator {
27 public final static String WEBSOCKET_SUBJECT = "org.argeo.cms.websocket.subject";
28
29 private final static CmsLog log = CmsLog.getLog(CmsWebSocketConfigurator.class);
30 final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
31
32 @Override
33 public boolean checkOrigin(String originHeaderValue) {
34 return true;
35 }
36
37 @Override
38 public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
39 try {
40 return endpointClass.getDeclaredConstructor().newInstance();
41 } catch (Exception e) {
42 throw new IllegalArgumentException("Cannot get endpoint instance", e);
43 }
44 }
45
46 @Override
47 public List<Extension> getNegotiatedExtensions(List<Extension> installed, List<Extension> requested) {
48 return requested;
49 }
50
51 @Override
52 public String getNegotiatedSubprotocol(List<String> supported, List<String> requested) {
53 if ((requested == null) || (requested.size() == 0))
54 return "";
55 if ((supported == null) || (supported.isEmpty()))
56 return "";
57 for (String possible : requested) {
58 if (possible == null)
59 continue;
60 if (supported.contains(possible))
61 return possible;
62 }
63 return "";
64 }
65
66 @Override
67 public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
68 if(true)
69 return;
70
71 RemoteAuthSession httpSession = new ServletHttpSession(
72 (javax.servlet.http.HttpSession) request.getHttpSession());
73 if (log.isDebugEnabled() && httpSession != null)
74 log.debug("Web socket HTTP session id: " + httpSession.getId());
75
76 if (httpSession == null) {
77 rejectResponse(response, null);
78 }
79 try {
80 LoginContext lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, new RemoteAuthCallbackHandler(httpSession));
81 lc.login();
82 if (log.isDebugEnabled())
83 log.debug("Web socket logged-in as " + lc.getSubject());
84 Subject.doAs(lc.getSubject(), new PrivilegedAction<Void>() {
85
86 @Override
87 public Void run() {
88 sec.getUserProperties().put(ServletContextHelper.REMOTE_USER, AccessController.getContext());
89 return null;
90 }
91
92 });
93 } catch (Exception e) {
94 rejectResponse(response, e);
95 }
96 }
97
98 /**
99 * Behaviour when the web socket could not be authenticated. Throws an
100 * {@link IllegalStateException} by default.
101 *
102 * @param e can be null
103 */
104 protected void rejectResponse(HandshakeResponse response, Exception e) {
105 // violent implementation, as suggested in
106 // https://stackoverflow.com/questions/21763829/jsr-356-how-to-abort-a-websocket-connection-during-the-handshake
107 // throw new IllegalStateException("Web socket cannot be authenticated");
108 }
109 }