This is an automated email from the ASF dual-hosted git repository. bhliva pushed a commit to branch v2.2-RC1 in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git
The following commit(s) were added to refs/heads/v2.2-RC1 by this push: new c595063 DLAB-000 fixed issue with unauthorized for web terminal c595063 is described below commit c595063b533db8f81f2715382b59317b91198d20 Author: bhliva <bohdan_hl...@epam.com> AuthorDate: Thu Nov 14 14:44:21 2019 +0200 DLAB-000 fixed issue with unauthorized for web terminal --- .../dlab/backendapi/SelfServiceApplication.java | 18 +----- .../servlet/guacamole/GuacamoleSecurityFilter.java | 71 ---------------------- .../servlet/guacamole/GuacamoleServlet.java | 30 ++++++++- .../src/app/webterminal/webterminal.component.ts | 4 +- 4 files changed, 31 insertions(+), 92 deletions(-) diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/SelfServiceApplication.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/SelfServiceApplication.java index 25d24e5..da6a5c5 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/SelfServiceApplication.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/SelfServiceApplication.java @@ -31,7 +31,6 @@ import com.epam.dlab.backendapi.modules.ModuleFactory; import com.epam.dlab.backendapi.resources.*; import com.epam.dlab.backendapi.resources.callback.*; import com.epam.dlab.backendapi.schedulers.internal.ManagedScheduler; -import com.epam.dlab.backendapi.servlet.guacamole.GuacamoleSecurityFilter; import com.epam.dlab.backendapi.servlet.guacamole.GuacamoleServlet; import com.epam.dlab.cloud.CloudModule; import com.epam.dlab.constants.ServiceConsts; @@ -58,15 +57,12 @@ import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.HandlerWrapper; -import javax.servlet.DispatcherType; -import java.util.EnumSet; - /** * Self Service based on Dropwizard application. */ @Slf4j public class SelfServiceApplication extends Application<SelfServiceApplicationConfiguration> { - private static final String GUACAMOLE_SERVLET_PATH = "/api/tunnel"; + public static final String GUACAMOLE_SERVLET_PATH = "/api/tunnel"; private static Injector appInjector; public static Injector getInjector() { @@ -94,12 +90,6 @@ public class SelfServiceApplication extends Application<SelfServiceApplicationCo )); bootstrap.addBundle(new DlabKeycloakBundle()); - /*bootstrap.addBundle(new SwaggerBundle<SelfServiceApplicationConfiguration>() { - @Override - protected SwaggerBundleConfiguration getSwaggerBundleConfiguration(SelfServiceApplicationConfiguration configuration) { - return configuration.getSwaggerConfiguration(); - } - });*/ } @Override @@ -125,12 +115,8 @@ public class SelfServiceApplication extends Application<SelfServiceApplicationCo environment.lifecycle().manage(injector.getInstance(ManagedScheduler.class)); environment.healthChecks().register(ServiceConsts.MONGO_NAME, injector.getInstance(MongoHealthCheck.class)); - final String guacamoleServletName = "GuacamoleServlet"; - environment.servlets().addServlet(guacamoleServletName, injector.getInstance(GuacamoleServlet.class)) + environment.servlets().addServlet("GuacamoleServlet", injector.getInstance(GuacamoleServlet.class)) .addMapping(GUACAMOLE_SERVLET_PATH); - environment.servlets().addFilter("GuacamoleSecurityFilter", - injector.getInstance(GuacamoleSecurityFilter.class)) - .addMappingForServletNames(EnumSet.allOf(DispatcherType.class), true, guacamoleServletName); JerseyEnvironment jersey = environment.jersey(); diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleSecurityFilter.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleSecurityFilter.java deleted file mode 100644 index f77b238..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleSecurityFilter.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.epam.dlab.backendapi.servlet.guacamole; - -import com.epam.dlab.auth.UserInfo; -import com.epam.dlab.backendapi.dao.SecurityDAO; -import com.google.inject.Inject; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.HttpHeaders; -import java.io.IOException; -import java.util.Optional; - -@Slf4j -public class GuacamoleSecurityFilter implements Filter { - private static final String AUTH_HEADER_PREFIX = "Bearer "; - - private final SecurityDAO securityDAO; - - @Inject - public GuacamoleSecurityFilter(SecurityDAO securityDAO) { - this.securityDAO = securityDAO; - } - - @Override - public void init(FilterConfig filterConfig) { - - } - - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { - HttpServletRequest request = (HttpServletRequest) servletRequest; - HttpServletResponse response = (HttpServletResponse) servletResponse; - final String authorization = request.getHeader(HttpHeaders.AUTHORIZATION); - final String credentials = StringUtils.substringAfter(authorization, AUTH_HEADER_PREFIX); - final Optional<UserInfo> user = securityDAO.getUser(credentials); - if (user.isPresent()) { - request.setAttribute(GuacamoleServlet.USER_ATTRIBUTE, user.get()); - filterChain.doFilter(servletRequest, servletResponse); - } else { - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - } - - } - - @Override - public void destroy() { - - } -} diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleServlet.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleServlet.java index 4933d7c..9c79bfa 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleServlet.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleServlet.java @@ -20,32 +20,47 @@ package com.epam.dlab.backendapi.servlet.guacamole; import com.epam.dlab.auth.UserInfo; +import com.epam.dlab.backendapi.dao.SecurityDAO; import com.epam.dlab.backendapi.service.GuacamoleService; +import com.epam.dlab.exceptions.DlabAuthenticationException; import com.epam.dlab.exceptions.DlabException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Inject; import lombok.Data; +import org.apache.commons.lang3.StringUtils; import org.apache.guacamole.net.GuacamoleTunnel; import org.apache.guacamole.servlet.GuacamoleHTTPTunnelServlet; +import org.apache.http.HttpStatus; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.core.HttpHeaders; import java.io.IOException; public class GuacamoleServlet extends GuacamoleHTTPTunnelServlet { - static final String USER_ATTRIBUTE = "user"; + private static final String UNAUTHORIZED_MSG = "User is not authenticated"; + private static final String DLAB_PREFIX = "DLab-"; private final GuacamoleService guacamoleService; private final ObjectMapper mapper; + private final SecurityDAO securityDAO; + private static final String AUTH_HEADER_PREFIX = "Bearer "; @Inject - public GuacamoleServlet(GuacamoleService guacamoleService, ObjectMapper mapper) { + public GuacamoleServlet(GuacamoleService guacamoleService, ObjectMapper mapper, SecurityDAO securityDAO) { this.mapper = mapper; this.guacamoleService = guacamoleService; + this.securityDAO = securityDAO; } @Override protected GuacamoleTunnel doConnect(HttpServletRequest request) { try { - final UserInfo userInfo = (UserInfo) request.getAttribute(USER_ATTRIBUTE); + final String authorization = request.getHeader(DLAB_PREFIX + HttpHeaders.AUTHORIZATION); + final String credentials = StringUtils.substringAfter(authorization, AUTH_HEADER_PREFIX); + final UserInfo userInfo = + securityDAO.getUser(credentials) + .orElseThrow(() -> new DlabAuthenticationException(UNAUTHORIZED_MSG)); final CreateTerminalDTO createTerminalDTO = mapper.readValue(request.getReader(), CreateTerminalDTO.class); return guacamoleService.getTunnel(userInfo, createTerminalDTO.getHost(), createTerminalDTO.getEndpoint()); } catch (IOException e) { @@ -53,6 +68,15 @@ public class GuacamoleServlet extends GuacamoleHTTPTunnelServlet { } } + @Override + protected void handleTunnelRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException { + try { + super.handleTunnelRequest(request, response); + } catch (DlabAuthenticationException e) { + sendError(response, HttpStatus.SC_UNAUTHORIZED, HttpStatus.SC_UNAUTHORIZED, UNAUTHORIZED_MSG); + } + } + @Data private static class CreateTerminalDTO { private String host; diff --git a/services/self-service/src/main/resources/webapp/src/app/webterminal/webterminal.component.ts b/services/self-service/src/main/resources/webapp/src/app/webterminal/webterminal.component.ts index dd05db0..8ec8127 100644 --- a/services/self-service/src/main/resources/webapp/src/app/webterminal/webterminal.component.ts +++ b/services/self-service/src/main/resources/webapp/src/app/webterminal/webterminal.component.ts @@ -62,7 +62,7 @@ export class WebterminalComponent implements OnInit { const url = environment.production ? window.location.origin : API_URL; const tunnel = new Guacamole.HTTPTunnel( `${url}/api/tunnel`, false, - { 'Authorization': `Bearer ${this.storageService.getToken()}` } + { 'DLab-Authorization': `Bearer ${this.storageService.getToken()}` } ); const guac = new Guacamole.Client(tunnel); @@ -91,4 +91,4 @@ export class WebterminalComponent implements OnInit { keyboard.onkeydown = (keysym) => guac.sendKeyEvent(1, keysym); keyboard.onkeyup = (keysym) => guac.sendKeyEvent(0, keysym); } -} \ No newline at end of file +} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@dlab.apache.org For additional commands, e-mail: commits-h...@dlab.apache.org