1 package org
.argeo
.cms
.websocket
;
5 import javax
.security
.auth
.login
.LoginContext
;
6 import javax
.servlet
.http
.HttpSession
;
7 import javax
.websocket
.Extension
;
8 import javax
.websocket
.HandshakeResponse
;
9 import javax
.websocket
.server
.HandshakeRequest
;
10 import javax
.websocket
.server
.ServerEndpointConfig
;
11 import javax
.websocket
.server
.ServerEndpointConfig
.Configurator
;
13 import org
.apache
.commons
.logging
.Log
;
14 import org
.apache
.commons
.logging
.LogFactory
;
15 import org
.argeo
.cms
.auth
.HttpRequestCallbackHandler
;
16 import org
.argeo
.node
.NodeConstants
;
18 /** Customises the initialisation of a new web socket. */
19 public class CmsWebSocketConfigurator
extends Configurator
{
20 public final static String WEBSOCKET_SUBJECT
= "org.argeo.cms.websocket.subject";
22 private final static Log log
= LogFactory
.getLog(CmsWebSocketConfigurator
.class);
23 final static String HEADER_WWW_AUTHENTICATE
= "WWW-Authenticate";
26 public boolean checkOrigin(String originHeaderValue
) {
31 public <T
> T
getEndpointInstance(Class
<T
> endpointClass
) throws InstantiationException
{
33 return endpointClass
.getDeclaredConstructor().newInstance();
34 } catch (Exception e
) {
35 throw new IllegalArgumentException("Cannot get endpoint instance", e
);
40 public List
<Extension
> getNegotiatedExtensions(List
<Extension
> installed
, List
<Extension
> requested
) {
45 public String
getNegotiatedSubprotocol(List
<String
> supported
, List
<String
> requested
) {
46 if ((requested
== null) || (requested
.size() == 0))
48 if ((supported
== null) || (supported
.isEmpty()))
50 for (String possible
: requested
) {
53 if (supported
.contains(possible
))
60 public void modifyHandshake(ServerEndpointConfig sec
, HandshakeRequest request
, HandshakeResponse response
) {
61 HttpSession httpSession
= (HttpSession
) request
.getHttpSession();
62 if (log
.isDebugEnabled() && httpSession
!= null)
63 log
.debug("Web socket HTTP session id: " + httpSession
.getId());
65 if (httpSession
== null) {
66 rejectResponse(response
, null);
69 LoginContext lc
= new LoginContext(NodeConstants
.LOGIN_CONTEXT_USER
,
70 new HttpRequestCallbackHandler(httpSession
));
72 if (log
.isDebugEnabled())
73 log
.debug("Web socket logged-in as " + lc
.getSubject());
74 sec
.getUserProperties().put(WEBSOCKET_SUBJECT
, lc
.getSubject());
75 } catch (Exception e
) {
76 rejectResponse(response
, e
);
81 * Behaviour when the web socket could not be authenticated. Throws an
82 * {@link IllegalStateException} by default.
84 * @param e can be null
86 protected void rejectResponse(HandshakeResponse response
, Exception e
) {
87 // violent implementation, as suggested in
88 // https://stackoverflow.com/questions/21763829/jsr-356-how-to-abort-a-websocket-connection-during-the-handshake
89 throw new IllegalStateException("Web socket cannot be authenticated");