From ff08a69e83ef0e332e64ea0aa4e457751258a52c Mon Sep 17 00:00:00 2001 From: Sunil G Date: Tue, 5 Jun 2018 00:47:30 +0530 Subject: [PATCH] YARN-8258 --- .../org/apache/hadoop/yarn/webapp/WebApps.java | 59 ++++++++++++++++------ .../resourcemanager/TestResourceManager.java | 31 ++++++++++++ 2 files changed, 74 insertions(+), 16 deletions(-) diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApps.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApps.java index 73644452140..003a93081b7 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApps.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApps.java @@ -44,6 +44,8 @@ import org.apache.hadoop.security.http.XFrameOptionsFilter; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.webapp.util.WebAppUtils; +import org.eclipse.jetty.servlet.FilterHolder; +import org.eclipse.jetty.servlet.FilterMapping; import org.eclipse.jetty.webapp.WebAppContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -424,7 +426,7 @@ public WebApp start(WebApp webapp, WebAppContext ui2Context) { WebApp webApp = build(webapp); HttpServer2 httpServer = webApp.httpServer(); if (ui2Context != null) { - addFiltersForNewContext(ui2Context); + addFiltersForUI2Context(ui2Context, httpServer); httpServer.addHandlerAtFront(ui2Context); } try { @@ -437,24 +439,49 @@ public WebApp start(WebApp webapp, WebAppContext ui2Context) { return webApp; } - private void addFiltersForNewContext(WebAppContext ui2Context) { - Map params = getConfigParameters(csrfConfigPrefix); - - if (hasCSRFEnabled(params)) { - LOG.info("CSRF Protection has been enabled for the {} application. " - + "Please ensure that there is an authentication mechanism " - + "enabled (kerberos, custom, etc).", name); - String restCsrfClassName = RestCsrfPreventionFilter.class.getName(); - HttpServer2.defineFilter(ui2Context, restCsrfClassName, - restCsrfClassName, params, new String[]{"/*"}); + private void addFiltersForUI2Context(WebAppContext ui2Context, + HttpServer2 httpServer) { + // Get filters and filtermappings from default context's servlet. + FilterHolder[] filterHolders = httpServer.getWebAppContext() + .getServletHandler().getFilters(); + FilterMapping[] filterMappingsArray = httpServer.getWebAppContext() + .getServletHandler().getFilterMappings(); + + // To define a filter for UI2 context, URL path also needed which is + // available only FilterMapping. Hence convert this to a map for easy + // access. + Map filterMappings = new HashMap<>(); + for (FilterMapping filterMapping : filterMappingsArray) { + filterMappings.put(filterMapping.getFilterName(), filterMapping); } - params = getConfigParameters(xfsConfigPrefix); + // Loop through all filterHolders and add one by one to UI2. + LOG.info("Add filters from default webapp context to UI2 context."); + for (FilterHolder filterHolder : filterHolders) { + // Skip guice filter for UI2. + if ("guice".equals(filterHolder.getName())) { + continue; + } + // Get the path spec from filtermapping for same filter name. + String[] pathSpecs = filterMappings.get(filterHolder.getName()) + .getPathSpecs(); + + // In case of Auth filter, also add "/*" so that all URLs under ui2 + // will be applicable for custom auth handler's like JWT (sso). + if ("authentication".equals(filterHolder.getName())) { + ArrayList paths = new ArrayList<>(); + paths.add("/*"); + HttpServer2.defineFilter(ui2Context, filterHolder.getName(), + filterHolder.getClassName(), filterHolder.getInitParameters(), + paths.toArray(new String[paths.size()])); + } else { + HttpServer2.defineFilter(ui2Context, filterHolder.getName(), + filterHolder.getClassName(), filterHolder.getInitParameters(), + pathSpecs); + } - if (hasXFSEnabled()) { - String xfsClassName = XFrameOptionsFilter.class.getName(); - HttpServer2.defineFilter(ui2Context, xfsClassName, xfsClassName, params, - new String[]{"/*"}); + LOG.info("UI2 context filter Name:" + filterHolder.getName() + + ", className=" + filterHolder.getClassName()); } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestResourceManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestResourceManager.java index 941e4775b2e..40f00ba6775 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestResourceManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestResourceManager.java @@ -27,6 +27,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.CommonConfigurationKeysPublic; import org.apache.hadoop.http.lib.StaticUserWebFilter; import org.apache.hadoop.net.NetworkTopology; import org.apache.hadoop.security.AuthenticationFilterInitializer; @@ -45,6 +46,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeUpdateSchedulerEvent; import org.apache.hadoop.yarn.server.security.http.RMAuthenticationFilterInitializer; import org.apache.hadoop.yarn.util.resource.Resources; +import org.eclipse.jetty.servlet.FilterHolder; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -316,4 +318,33 @@ protected void doSecureLogin() throws IOException { } } + @Test + public void testWebFilterOrder() throws Exception { + YarnConfiguration conf = new YarnConfiguration(); + String[] filterNamesArray = { "NoCacheFilter", "safety", + "RMAuthenticationFilter", + "org.apache.hadoop.security.http.XFrameOptionsFilter", "guice" }; + + conf.setBoolean(MockRM.ENABLE_WEBAPP, true); + conf.setBoolean(YarnConfiguration.YARN_ACL_ENABLE, true); + conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION, + "kerberos"); + conf.setBoolean(YarnConfiguration.RM_WEBAPP_DELEGATION_TOKEN_AUTH_FILTER, + true); + conf.set("hadoop.http.filter.initializers", + RMAuthenticationFilterInitializer.class.getName()); + MockRM rm = new MockRM(conf); + rm.init(conf); + rm.start(); + + FilterHolder[] filterHolders = rm.getWebapp().httpServer() + .getWebAppContext().getServletHandler().getFilters(); + Assert.assertEquals(filterHolders.length, 5); + for (int index = 0; index < filterHolders.length; index++) { + Assert.assertTrue( + filterHolders[index].getName().equals(filterNamesArray[index])); + } + + rm.stop(); + } } -- 2.14.3 (Apple Git-98)