]> git.argeo.org Git - lgpl/argeo-commons.git/blob - argeo/cms/websocket/server/CmsWebSocketConfigurator.java
Prepare next development cycle
[lgpl/argeo-commons.git] / argeo / cms / websocket / server / CmsWebSocketConfigurator.java
1 package org.argeo.cms.websocket.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.api.cms.CmsState;
18 import org.argeo.cms.auth.RemoteAuthCallbackHandler;
19 import org.argeo.cms.auth.RemoteAuthSession;
20 import org.argeo.cms.servlet.ServletHttpSession;
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 public final static String REMOTE_USER = "org.osgi.service.http.authentication.remote.user";
29
30 private final static CmsLog log = CmsLog.getLog(CmsWebSocketConfigurator.class);
31 final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
32
33 private CmsState cmsState;
34
35 public void start() {
36
37 }
38
39 public void stop() {
40
41 }
42
43 @Override
44 public boolean checkOrigin(String originHeaderValue) {
45 return true;
46 }
47
48 @Override
49 public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
50 try {
51 return endpointClass.getDeclaredConstructor().newInstance();
52 } catch (Exception e) {
53 throw new IllegalArgumentException("Cannot get endpoint instance", e);
54 }
55 }
56
57 @Override
58 public List<Extension> getNegotiatedExtensions(List<Extension> installed, List<Extension> requested) {
59 return requested;
60 }
61
62 @Override
63 public String getNegotiatedSubprotocol(List<String> supported, List<String> requested) {
64 if ((requested == null) || (requested.size() == 0))
65 return "";
66 if ((supported == null) || (supported.isEmpty()))
67 return "";
68 for (String possible : requested) {
69 if (possible == null)
70 continue;
71 if (supported.contains(possible))
72 return possible;
73 }
74 return "";
75 }
76
77 @Override
78 public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
79 if (true)
80 return;
81
82 RemoteAuthSession httpSession = new ServletHttpSession(
83 (javax.servlet.http.HttpSession) request.getHttpSession());
84 if (log.isDebugEnabled() && httpSession != null)
85 log.debug("Web socket HTTP session id: " + httpSession.getId());
86
87 if (httpSession == null) {
88 rejectResponse(response, null);
89 }
90 try {
91 LoginContext lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, new RemoteAuthCallbackHandler(httpSession));
92 lc.login();
93 if (log.isDebugEnabled())
94 log.debug("Web socket logged-in as " + lc.getSubject());
95 Subject.doAs(lc.getSubject(), new PrivilegedAction<Void>() {
96
97 @Override
98 public Void run() {
99 sec.getUserProperties().put(REMOTE_USER, AccessController.getContext());
100 return null;
101 }
102
103 });
104 } catch (Exception e) {
105 rejectResponse(response, e);
106 }
107 }
108
109 /**
110 * Behaviour when the web socket could not be authenticated. Throws an
111 * {@link IllegalStateException} by default.
112 *
113 * @param e can be null
114 */
115 protected void rejectResponse(HandshakeResponse response, Exception e) {
116 // violent implementation, as suggested in
117 // https://stackoverflow.com/questions/21763829/jsr-356-how-to-abort-a-websocket-connection-during-the-handshake
118 // throw new IllegalStateException("Web socket cannot be authenticated");
119 }
120 }