1 package org
.argeo
.cms
.websocket
.server
;
3 import java
.util
.ArrayList
;
6 import javax
.security
.auth
.login
.LoginContext
;
7 import javax
.security
.auth
.login
.LoginException
;
8 import javax
.websocket
.Extension
;
9 import javax
.websocket
.HandshakeResponse
;
10 import javax
.websocket
.server
.HandshakeRequest
;
11 import javax
.websocket
.server
.ServerEndpointConfig
;
12 import javax
.websocket
.server
.ServerEndpointConfig
.Configurator
;
14 import org
.argeo
.api
.cms
.CmsAuth
;
15 import org
.argeo
.api
.cms
.CmsLog
;
16 import org
.argeo
.cms
.auth
.RemoteAuthCallbackHandler
;
17 import org
.argeo
.cms
.auth
.RemoteAuthRequest
;
18 import org
.argeo
.cms
.auth
.RemoteAuthResponse
;
19 import org
.argeo
.cms
.auth
.RemoteAuthSession
;
20 import org
.argeo
.cms
.auth
.RemoteAuthUtils
;
21 import org
.argeo
.cms
.servlet
.CmsServletContext
;
24 * <strong>Disabled until third party issues are solved.</strong>. Customises
25 * the initialisation of a new web socket.
27 public class CmsWebSocketConfigurator
extends Configurator
{
29 private final static CmsLog log
= CmsLog
.getLog(CmsWebSocketConfigurator
.class);
31 private final String httpAuthRealm
= "Argeo";
34 public boolean checkOrigin(String originHeaderValue
) {
39 public <T
> T
getEndpointInstance(Class
<T
> endpointClass
) throws InstantiationException
{
41 return endpointClass
.getDeclaredConstructor().newInstance();
42 } catch (Exception e
) {
43 throw new IllegalArgumentException("Cannot get endpoint instance", e
);
48 public List
<Extension
> getNegotiatedExtensions(List
<Extension
> installed
, List
<Extension
> requested
) {
53 public String
getNegotiatedSubprotocol(List
<String
> supported
, List
<String
> requested
) {
54 if ((requested
== null) || (requested
.size() == 0))
56 if ((supported
== null) || (supported
.isEmpty()))
58 for (String possible
: requested
) {
61 if (supported
.contains(possible
))
68 public void modifyHandshake(ServerEndpointConfig sec
, HandshakeRequest request
, HandshakeResponse response
) {
72 WebSocketHandshakeRequest remoteAuthRequest
= new WebSocketHandshakeRequest(request
);
73 WebSocketHandshakeResponse remoteAuthResponse
= new WebSocketHandshakeResponse(response
);
74 // RemoteAuthSession httpSession = new ServletHttpSession(
75 // (javax.servlet.http.HttpSession) request.getHttpSession());
76 RemoteAuthSession remoteAuthSession
= remoteAuthRequest
.getSession();
77 if (log
.isDebugEnabled() && remoteAuthSession
!= null)
78 log
.debug("Web socket HTTP session id: " + remoteAuthSession
.getId());
80 // if (remoteAuthSession == null) {
81 // rejectResponse(response, null);
83 ClassLoader currentThreadContextClassLoader
= Thread
.currentThread().getContextClassLoader();
84 Thread
.currentThread().setContextClassLoader(CmsServletContext
.class.getClassLoader());
87 lc
= CmsAuth
.USER
.newLoginContext(new RemoteAuthCallbackHandler(remoteAuthRequest
, remoteAuthResponse
));
89 } catch (LoginException e
) {
90 if (authIsRequired(remoteAuthRequest
, remoteAuthResponse
)) {
91 int statusCode
= RemoteAuthUtils
.askForWwwAuth(remoteAuthRequest
, remoteAuthResponse
, httpAuthRealm
,
93 // remoteAuthResponse.setHeader("Status-Code", Integer.toString(statusCode));
96 lc
= RemoteAuthUtils
.anonymousLogin(remoteAuthRequest
, remoteAuthResponse
);
99 rejectResponse(response
, e
);
103 Thread
.currentThread().setContextClassLoader(currentThreadContextClassLoader
);
106 // Subject subject = lc.getSubject();
107 // Subject.doAs(subject, new PrivilegedAction<Void>() {
110 // public Void run() {
111 // // TODO also set login context in order to log out ?
112 // RemoteAuthUtils.configureRequestSecurity(remoteAuthRequest);
119 protected boolean authIsRequired(RemoteAuthRequest remoteAuthRequest
, RemoteAuthResponse remoteAuthResponse
) {
124 * Behaviour when the web socket could not be authenticated. Throws an
125 * {@link IllegalStateException} by default.
127 * @param e can be null
129 protected void rejectResponse(HandshakeResponse response
, Exception e
) {
130 response
.getHeaders().put(HandshakeResponse
.SEC_WEBSOCKET_ACCEPT
, new ArrayList
<String
>());
131 // violent implementation, as suggested in
132 // https://stackoverflow.com/questions/21763829/jsr-356-how-to-abort-a-websocket-connection-during-the-handshake
133 // throw new IllegalStateException("Web socket cannot be authenticated");