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