Search in sources :

Example 1 with WebsocketAdapter

use of org.openremote.container.web.socket.WebsocketAdapter in project openremote by openremote.

the class DefaultWebsocketComponent method deploy.

@Override
protected void deploy() throws Exception {
    WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
    getConsumers().entrySet().forEach(consumerEntry -> {
        String endpointPath = MessageBrokerSetupService.WEBSOCKET_PATH + "/" + consumerEntry.getKey();
        LOG.info("Deploying websocket endpoint: " + endpointPath);
        webSocketDeploymentInfo.addEndpoint(ServerEndpointConfig.Builder.create(WebsocketAdapter.class, endpointPath).configurator(new DefaultContainerConfigurator() {

            @SuppressWarnings("unchecked")
            @Override
            public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
                return (T) new WebsocketAdapter(consumerEntry.getValue());
            }

            @SuppressWarnings("unchecked")
            @Override
            public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
                Principal principal = request.getUserPrincipal();
                if (principal == null) {
                    throw new WebApplicationException("Request is not authenticated, can't access user principal", FORBIDDEN);
                }
                AuthContext authContext;
                if (principal instanceof KeycloakPrincipal) {
                    KeycloakPrincipal keycloakPrincipal = (KeycloakPrincipal) principal;
                    authContext = new AccessTokenAuthContext(keycloakPrincipal.getKeycloakSecurityContext().getRealm(), keycloakPrincipal.getKeycloakSecurityContext().getToken());
                } else if (principal instanceof BasicAuthContext) {
                    authContext = (BasicAuthContext) principal;
                } else {
                    throw new WebApplicationException("Unsupported user principal type: " + principal, INTERNAL_SERVER_ERROR);
                }
                config.getUserProperties().put(WebsocketConstants.HANDSHAKE_AUTH, authContext);
                super.modifyHandshake(config, request, response);
            }
        }).build());
    });
    // We use the I/O thread to handle received websocket frames, as we expect to quickly hand them over to
    // an internal asynchronous message queue for processing, so we don't need a separate worker thread
    // pool for websocket frame processing
    webSocketDeploymentInfo.setDispatchToWorkerThread(false);
    // Make the shit Undertow/Websocket JSR client bootstrap happy - this is the pool that would be used
    // when Undertow acts as a WebSocket client, which we don't do... and I'm not even sure it can do that...
    webSocketDeploymentInfo.setWorker(Xnio.getInstance().createWorker(OptionMap.builder().set(Options.WORKER_TASK_MAX_THREADS, 1).set(Options.WORKER_NAME, "WebsocketInternalClient").set(Options.THREAD_DAEMON, true).getMap()));
    boolean directBuffers = Boolean.getBoolean("io.undertow.websockets.direct-buffers");
    webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(directBuffers, 1024, 100, 12));
    deploymentInfo = new DeploymentInfo().setDeploymentName("WebSocket Deployment").setContextPath(MessageBrokerSetupService.WEBSOCKET_PATH).addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME, webSocketDeploymentInfo).setClassLoader(WebsocketComponent.class.getClassLoader());
    WebResourceCollection resourceCollection = new WebResourceCollection();
    resourceCollection.addUrlPattern("/*");
    // Require authentication, but authorize specific roles later in Camel
    SecurityConstraint constraint = new SecurityConstraint();
    constraint.setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.AUTHENTICATE);
    constraint.addWebResourceCollection(resourceCollection);
    deploymentInfo.addSecurityConstraints(constraint);
    HttpHandler handler = webService.addServletDeployment(identityService, deploymentInfo, true);
    webService.getPrefixRoutes().put(MessageBrokerSetupService.WEBSOCKET_PATH, handler);
}
Also used : HttpHandler(io.undertow.server.HttpHandler) WebApplicationException(javax.ws.rs.WebApplicationException) DefaultByteBufferPool(io.undertow.server.DefaultByteBufferPool) ServerEndpointConfig(javax.websocket.server.ServerEndpointConfig) BasicAuthContext(org.openremote.container.security.basic.BasicAuthContext) AccessTokenAuthContext(org.openremote.container.security.keycloak.AccessTokenAuthContext) AuthContext(org.openremote.container.security.AuthContext) BasicAuthContext(org.openremote.container.security.basic.BasicAuthContext) WebSocketDeploymentInfo(io.undertow.websockets.jsr.WebSocketDeploymentInfo) HandshakeResponse(javax.websocket.HandshakeResponse) WebsocketAdapter(org.openremote.container.web.socket.WebsocketAdapter) AccessTokenAuthContext(org.openremote.container.security.keycloak.AccessTokenAuthContext) WebSocketDeploymentInfo(io.undertow.websockets.jsr.WebSocketDeploymentInfo) DefaultContainerConfigurator(io.undertow.websockets.jsr.DefaultContainerConfigurator) KeycloakPrincipal(org.keycloak.KeycloakPrincipal) Principal(java.security.Principal) HandshakeRequest(javax.websocket.server.HandshakeRequest) KeycloakPrincipal(org.keycloak.KeycloakPrincipal)

Aggregations

DefaultByteBufferPool (io.undertow.server.DefaultByteBufferPool)1 HttpHandler (io.undertow.server.HttpHandler)1 DefaultContainerConfigurator (io.undertow.websockets.jsr.DefaultContainerConfigurator)1 WebSocketDeploymentInfo (io.undertow.websockets.jsr.WebSocketDeploymentInfo)1 Principal (java.security.Principal)1 HandshakeResponse (javax.websocket.HandshakeResponse)1 HandshakeRequest (javax.websocket.server.HandshakeRequest)1 ServerEndpointConfig (javax.websocket.server.ServerEndpointConfig)1 WebApplicationException (javax.ws.rs.WebApplicationException)1 KeycloakPrincipal (org.keycloak.KeycloakPrincipal)1 AuthContext (org.openremote.container.security.AuthContext)1 BasicAuthContext (org.openremote.container.security.basic.BasicAuthContext)1 AccessTokenAuthContext (org.openremote.container.security.keycloak.AccessTokenAuthContext)1 WebsocketAdapter (org.openremote.container.web.socket.WebsocketAdapter)1