Return-Path: X-Original-To: apmail-ambari-commits-archive@www.apache.org Delivered-To: apmail-ambari-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 0980511A63 for ; Wed, 10 Sep 2014 00:02:02 +0000 (UTC) Received: (qmail 44209 invoked by uid 500); 10 Sep 2014 00:02:02 -0000 Delivered-To: apmail-ambari-commits-archive@ambari.apache.org Received: (qmail 44181 invoked by uid 500); 10 Sep 2014 00:02:01 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 44172 invoked by uid 99); 10 Sep 2014 00:02:01 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 10 Sep 2014 00:02:01 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 8E39F8864; Wed, 10 Sep 2014 00:02:01 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jaimin@apache.org To: commits@ambari.apache.org Message-Id: <1349b13308594fc9bed52f687aba0f44@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: git commit: AMBARI-7232. Admin View: Views API should not allow access to Admin View UI by non-Admin users. (jaimin) Date: Wed, 10 Sep 2014 00:02:01 +0000 (UTC) Repository: ambari Updated Branches: refs/heads/trunk 00be663b5 -> 3c30d9158 AMBARI-7232. Admin View: Views API should not allow access to Admin View UI by non-Admin users. (jaimin) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/3c30d915 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/3c30d915 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/3c30d915 Branch: refs/heads/trunk Commit: 3c30d9158db2902f6fca3856b65d4a98886e23f2 Parents: 00be663 Author: Jaimin Jetly Authored: Tue Sep 9 17:01:59 2014 -0700 Committer: Jaimin Jetly Committed: Tue Sep 9 17:01:59 2014 -0700 ---------------------------------------------------------------------- .../ambari/server/api/AmbariPersistFilter.java | 1 - .../server/controller/AmbariHandlerList.java | 43 ++++++++-- .../ambari/server/controller/AmbariServer.java | 26 ++++-- .../server/controller/ControllerModule.java | 69 +++++++++------ .../controller/FailsafeServletResponse.java | 22 ++++- .../server/orm/entities/ViewInstanceEntity.java | 89 ++++++++++++++++++++ .../ambari/server/security/SecurityFilter.java | 2 +- .../AmbariAuthorizationFilter.java | 35 ++++++-- .../orm/entities/ViewInstanceEntityTest.java | 16 ++++ 9 files changed, 254 insertions(+), 49 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/3c30d915/ambari-server/src/main/java/org/apache/ambari/server/api/AmbariPersistFilter.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/AmbariPersistFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/api/AmbariPersistFilter.java index 971b8a0..a5ab041 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/AmbariPersistFilter.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/AmbariPersistFilter.java @@ -19,7 +19,6 @@ package org.apache.ambari.server.api; import com.google.inject.Inject; import com.google.inject.Singleton; -import com.google.inject.persist.PersistService; import com.google.inject.persist.UnitOfWork; import javax.servlet.*; http://git-wip-us.apache.org/repos/asf/ambari/blob/3c30d915/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java index 2dc3f47..6a831f8 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java @@ -17,6 +17,12 @@ */ package org.apache.ambari.server.controller; +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Singleton; + import org.apache.ambari.server.orm.entities.ViewEntity; import org.apache.ambari.server.orm.entities.ViewInstanceEntity; import org.apache.ambari.server.view.ViewContextImpl; @@ -25,12 +31,12 @@ import org.apache.ambari.server.view.ViewRegistry; import org.apache.ambari.view.SystemException; import org.apache.ambari.view.ViewContext; import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.SessionManager; +import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.webapp.WebAppContext; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.HashMap; -import java.util.Map; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.GenericWebApplicationContext; +import org.springframework.web.filter.DelegatingFilterProxy; /** * An Ambari specific extension of the FailsafeHandlerList that allows for the addition @@ -46,6 +52,15 @@ public class AmbariHandlerList extends FailsafeHandlerList implements ViewInstan ViewRegistry viewRegistry; /** + * Session manager. + */ + @Inject + SessionManager sessionManager; + + @Inject + DelegatingFilterProxy springSecurityFilter; + + /** * The Handler factory. */ private final HandlerFactory handlerFactory; @@ -55,6 +70,10 @@ public class AmbariHandlerList extends FailsafeHandlerList implements ViewInstan */ private final Map handlerMap = new HashMap(); + /** + * Spring web app context. + */ + private GenericWebApplicationContext springWebAppContext; // ----- Constructors ------------------------------------------------------ @@ -72,6 +91,10 @@ public class AmbariHandlerList extends FailsafeHandlerList implements ViewInstan context.setClassLoader(viewInstanceDefinition.getViewEntity().getClassLoader()); context.setAttribute(ViewContext.CONTEXT_ATTRIBUTE, new ViewContextImpl(viewInstanceDefinition, viewRegistry)); + context.getSessionHandler().setSessionManager(sessionManager); + context.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, springWebAppContext); + context.addFilter(new FilterHolder(springSecurityFilter), "/*", 1); + return context; } }; @@ -87,6 +110,16 @@ public class AmbariHandlerList extends FailsafeHandlerList implements ViewInstan this.handlerFactory = handlerFactory; } + /** + * Sets the spring web app context. + * + * @param springWebAppContext the spring web app context + */ + public void setSpringWebAppContext( + GenericWebApplicationContext springWebAppContext) { + this.springWebAppContext = springWebAppContext; + } + // ----- ViewInstanceHandler ----------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/3c30d915/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java index 4e0d092..fc74e00 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java @@ -75,10 +75,10 @@ import org.apache.ambari.server.resources.api.rest.GetResource; import org.apache.ambari.server.scheduler.ExecutionScheduleManager; import org.apache.ambari.server.security.CertificateManager; import org.apache.ambari.server.security.SecurityFilter; +import org.apache.ambari.server.security.authorization.AmbariAuthorizationFilter; import org.apache.ambari.server.security.authorization.AmbariLdapAuthenticationProvider; import org.apache.ambari.server.security.authorization.AmbariLocalUserDetailsService; import org.apache.ambari.server.security.authorization.Users; -import org.apache.ambari.server.security.authorization.AmbariAuthorizationFilter; import org.apache.ambari.server.security.authorization.internal.AmbariInternalAuthenticationProvider; import org.apache.ambari.server.security.ldap.AmbariLdapDataPopulator; import org.apache.ambari.server.security.unsecured.rest.CertificateDownload; @@ -91,6 +91,8 @@ import org.apache.ambari.server.utils.VersionUtils; import org.apache.ambari.server.view.ViewRegistry; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.SessionIdManager; +import org.eclipse.jetty.server.SessionManager; import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.server.ssl.SslSelectChannelConnector; import org.eclipse.jetty.servlet.DefaultServlet; @@ -154,6 +156,21 @@ public class AmbariServer { @Inject AmbariHandlerList handlerList; + /** + * Session manager. + */ + @Inject + SessionManager sessionManager; + + /** + * Session ID manager. + */ + @Inject + SessionIdManager sessionIdManager; + + @Inject + DelegatingFilterProxy springSecurityFilter; + public String getServerOsType() { return configs.getServerOsType(); } @@ -173,6 +190,7 @@ public class AmbariServer { performStaticInjection(); initDB(); server = new Server(); + server.setSessionIdManager(sessionIdManager); Server serverForAgent = new Server(); checkDBVersion(); @@ -210,6 +228,7 @@ public class AmbariServer { root.setContextPath(CONTEXT_PATH); root.setErrorHandler(injector.getInstance(AmbariErrorHandler.class)); + root.getSessionHandler().setSessionManager(sessionManager); //Changing session cookie name to avoid conflicts root.getSessionHandler().getSessionManager().setSessionCookie("AMBARISESSIONID"); @@ -223,6 +242,7 @@ public class AmbariServer { root.getServletContext().setAttribute( WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, springWebAppContext); + handlerList.setSpringWebAppContext(springWebAppContext); certMan.initRootCert(); @@ -237,10 +257,6 @@ public class AmbariServer { rootServlet = agentroot.addServlet(DefaultServlet.class, "/"); rootServlet.setInitOrder(1); - //Spring Security Filter initialization - DelegatingFilterProxy springSecurityFilter = new DelegatingFilterProxy(); - springSecurityFilter.setTargetBeanName("springSecurityFilterChain"); - //session-per-request strategy for api and agents root.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/api/*", 1); root.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/proxy/*", 1); http://git-wip-us.apache.org/repos/asf/ambari/blob/3c30d915/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java index fa785c8..c395df6 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java @@ -18,14 +18,24 @@ package org.apache.ambari.server.controller; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.inject.AbstractModule; -import com.google.inject.Scopes; -import com.google.inject.assistedinject.FactoryModuleBuilder; -import com.google.inject.name.Names; -import com.google.inject.persist.PersistModule; -import com.google.inject.persist.jpa.AmbariJpaPersistModule; +import static org.eclipse.persistence.config.PersistenceUnitProperties.CREATE_JDBC_DDL_FILE; +import static org.eclipse.persistence.config.PersistenceUnitProperties.CREATE_ONLY; +import static org.eclipse.persistence.config.PersistenceUnitProperties.CREATE_OR_EXTEND; +import static org.eclipse.persistence.config.PersistenceUnitProperties.DDL_BOTH_GENERATION; +import static org.eclipse.persistence.config.PersistenceUnitProperties.DDL_GENERATION; +import static org.eclipse.persistence.config.PersistenceUnitProperties.DDL_GENERATION_MODE; +import static org.eclipse.persistence.config.PersistenceUnitProperties.DROP_AND_CREATE; +import static org.eclipse.persistence.config.PersistenceUnitProperties.DROP_JDBC_DDL_FILE; +import static org.eclipse.persistence.config.PersistenceUnitProperties.JDBC_DRIVER; +import static org.eclipse.persistence.config.PersistenceUnitProperties.JDBC_PASSWORD; +import static org.eclipse.persistence.config.PersistenceUnitProperties.JDBC_URL; +import static org.eclipse.persistence.config.PersistenceUnitProperties.JDBC_USER; +import static org.eclipse.persistence.config.PersistenceUnitProperties.THROW_EXCEPTIONS; + +import java.security.SecureRandom; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; import org.apache.ambari.server.actionmanager.ActionDBAccessor; import org.apache.ambari.server.actionmanager.ActionDBAccessorImpl; @@ -77,27 +87,22 @@ import org.apache.ambari.server.state.scheduler.RequestExecutionFactory; import org.apache.ambari.server.state.scheduler.RequestExecutionImpl; import org.apache.ambari.server.state.svccomphost.ServiceComponentHostImpl; import org.apache.ambari.server.view.ViewInstanceHandlerList; +import org.eclipse.jetty.server.SessionIdManager; +import org.eclipse.jetty.server.SessionManager; +import org.eclipse.jetty.server.session.HashSessionIdManager; +import org.eclipse.jetty.server.session.HashSessionManager; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.StandardPasswordEncoder; +import org.springframework.web.filter.DelegatingFilterProxy; -import java.security.SecureRandom; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import static org.eclipse.persistence.config.PersistenceUnitProperties.CREATE_JDBC_DDL_FILE; -import static org.eclipse.persistence.config.PersistenceUnitProperties.CREATE_ONLY; -import static org.eclipse.persistence.config.PersistenceUnitProperties.CREATE_OR_EXTEND; -import static org.eclipse.persistence.config.PersistenceUnitProperties.DDL_BOTH_GENERATION; -import static org.eclipse.persistence.config.PersistenceUnitProperties.DDL_GENERATION; -import static org.eclipse.persistence.config.PersistenceUnitProperties.DDL_GENERATION_MODE; -import static org.eclipse.persistence.config.PersistenceUnitProperties.DROP_AND_CREATE; -import static org.eclipse.persistence.config.PersistenceUnitProperties.DROP_JDBC_DDL_FILE; -import static org.eclipse.persistence.config.PersistenceUnitProperties.JDBC_DRIVER; -import static org.eclipse.persistence.config.PersistenceUnitProperties.JDBC_PASSWORD; -import static org.eclipse.persistence.config.PersistenceUnitProperties.JDBC_URL; -import static org.eclipse.persistence.config.PersistenceUnitProperties.JDBC_USER; -import static org.eclipse.persistence.config.PersistenceUnitProperties.THROW_EXCEPTIONS; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.inject.AbstractModule; +import com.google.inject.Scopes; +import com.google.inject.assistedinject.FactoryModuleBuilder; +import com.google.inject.name.Names; +import com.google.inject.persist.PersistModule; +import com.google.inject.persist.jpa.AmbariJpaPersistModule; /** * Used for injection purposes. @@ -168,9 +173,21 @@ public class ControllerModule extends AbstractModule { protected void configure() { installFactories(); + final SessionIdManager sessionIdManager = new HashSessionIdManager(); + final SessionManager sessionManager = new HashSessionManager(); + sessionManager.setSessionPath("/"); + sessionManager.setSessionIdManager(sessionIdManager); + bind(SessionManager.class).toInstance(sessionManager); + bind(SessionIdManager.class).toInstance(sessionIdManager); + bind(Configuration.class).toInstance(configuration); bind(HostsMap.class).toInstance(hostsMap); bind(PasswordEncoder.class).toInstance(new StandardPasswordEncoder()); + bind(DelegatingFilterProxy.class).toInstance(new DelegatingFilterProxy() { + { + setTargetBeanName("springSecurityFilterChain"); + } + }); bind(Gson.class).annotatedWith(Names.named("prettyGson")).toInstance(prettyGson); install(buildJpaPersistModule()); http://git-wip-us.apache.org/repos/asf/ambari/blob/3c30d915/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeServletResponse.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeServletResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeServletResponse.java index bad6e22..094c4c5 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeServletResponse.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeServletResponse.java @@ -18,6 +18,8 @@ package org.apache.ambari.server.controller; import java.io.IOException; +import java.util.Arrays; +import java.util.List; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; @@ -27,9 +29,17 @@ import javax.servlet.http.HttpServletResponseWrapper; * errors on failed requests. */ public class FailsafeServletResponse extends HttpServletResponseWrapper { + /** + * Indicates that request failed. + */ private boolean error; /** + * List of errors which should not be consumed by fail-safe handler. + */ + private List allowedErrors = Arrays.asList(HttpServletResponse.SC_FORBIDDEN); + + /** * Constructor. * * @param response response to be wrapped @@ -40,12 +50,20 @@ public class FailsafeServletResponse extends HttpServletResponseWrapper { @Override public void sendError(int sc) throws IOException { - error = true; + if (allowedErrors.contains(sc)) { + super.sendError(sc); + } else { + error = true; + } } @Override public void sendError(int sc, String msg) throws IOException { - error = true; + if (allowedErrors.contains(sc)) { + super.sendError(sc, msg); + } else { + error = true; + } } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/3c30d915/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java index 8fa700e..f84be60 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java @@ -23,6 +23,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.persistence.Basic; import javax.persistence.CascadeType; @@ -73,6 +75,11 @@ public class ViewInstanceEntity implements ViewInstanceDefinition { */ public static final String VIEWS_CONTEXT_PATH_PREFIX = "/views/"; + /** + * The pattern for matching view instance context path. + */ + public static final String VIEWS_CONTEXT_PATH_PATTERN = "" + VIEWS_CONTEXT_PATH_PREFIX + "([^/]+)/([^/]+)/([^/]+)(.*)"; + @Id @Column(name = "view_instance_id", nullable = false) @GeneratedValue(strategy = GenerationType.TABLE, generator = "view_instance_id_generator") @@ -677,6 +684,25 @@ public class ViewInstanceEntity implements ViewInstanceDefinition { } /** + * Parses context path into view name, version and instance name + * + * @param contextPath the context path + * @return null if context path doesn't match correct pattern + */ + public static ViewInstanceVersionDTO parseContextPath(String contextPath) { + final Pattern pattern = Pattern.compile(VIEWS_CONTEXT_PATH_PATTERN); + Matcher matcher = pattern.matcher(contextPath); + if (!matcher.matches()) { + return null; + } else { + final String viewName = matcher.group(1); + final String version = matcher.group(2); + final String instanceName = matcher.group(3); + return new ViewInstanceVersionDTO(viewName, version, instanceName); + } + } + + /** * Get the current user name. * * @return the current user name; empty String if user is not known @@ -768,4 +794,67 @@ public class ViewInstanceEntity implements ViewInstanceDefinition { result = 31 * result + name.hashCode(); return result; } + + //----- ViewInstanceVersionDTO inner class -------------------------------------------------- + + /** + * Keeps information about view name, version and instance name. + */ + public static class ViewInstanceVersionDTO { + + /** + * View name. + */ + private final String viewName; + + /** + * View version. + */ + private final String version; + + /** + * View instance name. + */ + private final String instanceName; + + /** + * Constructor. + * + * @param viewName view name + * @param version view version + * @param instanceName view instance name + */ + public ViewInstanceVersionDTO(String viewName, String version, String instanceName) { + this.viewName = viewName; + this.version = version; + this.instanceName = instanceName; + } + + /** + * Get the view name. + * + * @return the view name + */ + public String getViewName() { + return viewName; + } + + /** + * Get the view version. + * + * @return the view version + */ + public String getVersion() { + return version; + } + + /** + * Get the view instance name. + * + * @return the view instance name + */ + public String getInstanceName() { + return instanceName; + } + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/3c30d915/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityFilter.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityFilter.java index a85189b..ad57547 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityFilter.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityFilter.java @@ -35,7 +35,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class SecurityFilter implements Filter { - + //Allowed pathes for one way auth https private static String CA = "/ca"; http://git-wip-us.apache.org/repos/asf/ambari/blob/3c30d915/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java index bc67cdb..aae967d 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java @@ -18,19 +18,28 @@ package org.apache.ambari.server.security.authorization; +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + import org.apache.ambari.server.orm.entities.PermissionEntity; import org.apache.ambari.server.orm.entities.PrivilegeEntity; +import org.apache.ambari.server.orm.entities.ViewInstanceEntity; +import org.apache.ambari.server.orm.entities.ViewInstanceEntity.ViewInstanceVersionDTO; import org.apache.ambari.server.security.authorization.internal.InternalAuthenticationToken; +import org.apache.ambari.server.view.ViewRegistry; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - public class AmbariAuthorizationFilter implements Filter { private static final String REALM_PARAM = "realm"; @@ -43,7 +52,6 @@ public class AmbariAuthorizationFilter implements Filter { */ private String realm; - @Override public void init(FilterConfig filterConfig) throws ServletException { realm = getParameterValue(filterConfig, REALM_PARAM, DEFAULT_REALM); @@ -51,9 +59,11 @@ public class AmbariAuthorizationFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - HttpServletRequest httpRequest = (HttpServletRequest) request; + HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; + String requestURI = httpRequest.getRequestURI(); + SecurityContext context = getSecurityContext(); Authentication authentication = context.getAuthentication(); @@ -71,7 +81,6 @@ public class AmbariAuthorizationFilter implements Filter { AmbariGrantedAuthority ambariGrantedAuthority = (AmbariGrantedAuthority) grantedAuthority; PrivilegeEntity privilegeEntity = ambariGrantedAuthority.getPrivilegeEntity(); - String requestURI = httpRequest.getRequestURI(); Integer permissionId = privilegeEntity.getPermission().getId(); // admin has full access @@ -101,7 +110,15 @@ public class AmbariAuthorizationFilter implements Filter { } } } - if (!authorized && !httpRequest.getMethod().equals("GET")) { + + if (!authorized && requestURI.matches(ViewInstanceEntity.VIEWS_CONTEXT_PATH_PATTERN)) { + final ViewInstanceVersionDTO dto = ViewInstanceEntity.parseContextPath(requestURI); + authorized = ViewRegistry.getInstance().checkPermission(dto.getViewName(), dto.getVersion(), dto.getInstanceName(), true); + } + + // allow GET for everything except views + if (!authorized && + (!httpRequest.getMethod().equals("GET") || requestURI.matches("/views.*"))) { httpResponse.setHeader("WWW-Authenticate", "Basic realm=\"" + realm + "\""); httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "You do not have permissions to access this resource."); http://git-wip-us.apache.org/repos/asf/ambari/blob/3c30d915/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewInstanceEntityTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewInstanceEntityTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewInstanceEntityTest.java index d943431..c0545da 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewInstanceEntityTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewInstanceEntityTest.java @@ -20,6 +20,7 @@ package org.apache.ambari.server.orm.entities; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.controller.spi.Resource; +import org.apache.ambari.server.orm.entities.ViewInstanceEntity.ViewInstanceVersionDTO; import org.apache.ambari.server.security.SecurityHelper; import org.apache.ambari.server.view.ViewRegistryTest; import org.apache.ambari.server.view.configuration.InstanceConfig; @@ -299,6 +300,21 @@ public class ViewInstanceEntityTest { } @Test + public void testParseContextPath() throws Exception { + final String[] pathesToTest = { + ViewInstanceEntity.VIEWS_CONTEXT_PATH_PREFIX + "MY_VIEW/1.0.0/INSTANCE1", + ViewInstanceEntity.VIEWS_CONTEXT_PATH_PREFIX + "MY_VIEW/1.0.0/INSTANCE1/index.html", + ViewInstanceEntity.VIEWS_CONTEXT_PATH_PREFIX + "MY_VIEW/1.0.0/INSTANCE1/api/test" + }; + for (String contextPath: pathesToTest) { + final ViewInstanceVersionDTO dto = ViewInstanceEntity.parseContextPath(contextPath); + Assert.assertEquals("INSTANCE1", dto.getInstanceName()); + Assert.assertEquals("MY_VIEW", dto.getViewName()); + Assert.assertEquals("1.0.0", dto.getVersion()); + } + } + + @Test public void testInstanceData() throws Exception { TestSecurityHelper securityHelper = new TestSecurityHelper("user1");