You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2015/10/14 04:25:21 UTC
ambari git commit: AMBARI-13351. Security-related HTTP headers should
be set separately for Ambari Views then for Ambari server UI (rlevas)
Repository: ambari
Updated Branches:
refs/heads/trunk 92915952a -> 31542ae31
AMBARI-13351. Security-related HTTP headers should be set separately for Ambari Views then for Ambari server UI (rlevas)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/31542ae3
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/31542ae3
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/31542ae3
Branch: refs/heads/trunk
Commit: 31542ae31be265e0fa309e3a33bccccc91b4cb90
Parents: 9291595
Author: Robert Levas <rl...@hortonworks.com>
Authored: Tue Oct 13 22:23:25 2015 -0400
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Tue Oct 13 22:25:15 2015 -0400
----------------------------------------------------------------------
ambari-server/conf/unix/ambari.properties | 9 +-
ambari-server/conf/windows/ambari.properties | 9 +-
.../server/configuration/Configuration.java | 65 +++-
.../server/controller/AmbariHandlerList.java | 8 +-
.../ambari/server/controller/AmbariServer.java | 4 +-
.../security/AbstractSecurityHeaderFilter.java | 143 ++++++++
.../AmbariServerSecurityHeaderFilter.java | 37 +++
.../AmbariViewsSecurityHeaderFilter.java | 37 +++
.../server/security/SecurityHeaderFilter.java | 121 -------
.../controller/AmbariHandlerListTest.java | 8 +-
.../AbstractSecurityHeaderFilterTest.java | 329 +++++++++++++++++++
.../AmbariServerSecurityHeaderFilterTest.java | 51 +++
.../AmbariViewsSecurityHeaderFilterTest.java | 52 +++
.../security/SecurityHeaderFilterTest.java | 318 ------------------
14 files changed, 734 insertions(+), 457 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/ambari-server/conf/unix/ambari.properties
----------------------------------------------------------------------
diff --git a/ambari-server/conf/unix/ambari.properties b/ambari-server/conf/unix/ambari.properties
index 68cbf65..53af453 100644
--- a/ambari-server/conf/unix/ambari.properties
+++ b/ambari-server/conf/unix/ambari.properties
@@ -97,7 +97,12 @@ skip.service.checks=false
rolling.upgrade.min.stack=HDP-2.2
rolling.upgrade.max.stack=
-# HTTP Header settings
+# HTTP Header settings for Ambari Server UI
http.strict-transport-security=max-age=31536000
http.x-xss-protection=1; mode=block
-http.x-frame-options=DENY
\ No newline at end of file
+http.x-frame-options=DENY
+
+# HTTP Header settings for Ambari Views
+views.http.strict-transport-security=max-age=31536000
+views.http.x-xss-protection=1; mode=block
+views.http.x-frame-options=SAMEORIGIN
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/ambari-server/conf/windows/ambari.properties
----------------------------------------------------------------------
diff --git a/ambari-server/conf/windows/ambari.properties b/ambari-server/conf/windows/ambari.properties
index 6a98a63..570e904 100644
--- a/ambari-server/conf/windows/ambari.properties
+++ b/ambari-server/conf/windows/ambari.properties
@@ -87,7 +87,12 @@ ulimit.open.files=10000
##server.jdbc.user.passwd=etc\\ambari-server\\conf\\password.dat
##server.jdbc.user.name=ambari
-# HTTP Header settings
+# HTTP Header settings for Ambari Server UI
http.strict-transport-security=max-age=31536000
http.x-xss-protection=1; mode=block
-http.x-frame-options=DENY
\ No newline at end of file
+http.x-frame-options=DENY
+
+# HTTP Header settings for Ambari Views
+views.http.strict-transport-security=max-age=31536000
+views.http.x-xss-protection=1; mode=block
+views.http.x-frame-options=SAMEORIGIN
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index c653e1b..23f9803fe 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -458,7 +458,7 @@ public class Configuration {
public static final String ALERTS_EXECUTION_SCHEDULER_THREADS_DEFAULT = "2";
/**
- * For HTTP Response header configuration
+ * For HTTP Response header configuration for Ambari Server UI
*/
public static final String HTTP_STRICT_TRANSPORT_HEADER_VALUE_KEY = "http.strict-transport-security";
public static final String HTTP_STRICT_TRANSPORT_HEADER_VALUE_DEFAULT = "max-age=31536000";
@@ -467,6 +467,16 @@ public class Configuration {
public static final String HTTP_X_XSS_PROTECTION_HEADER_VALUE_KEY = "http.x-xss-protection";
public static final String HTTP_X_XSS_PROTECTION_HEADER_VALUE_DEFAULT = "1; mode=block";
+ /**
+ * For HTTP Response header configuration for Ambari Views
+ */
+ public static final String VIEWS_HTTP_STRICT_TRANSPORT_HEADER_VALUE_KEY = "views.http.strict-transport-security";
+ public static final String VIEWS_HTTP_STRICT_TRANSPORT_HEADER_VALUE_DEFAULT = "max-age=31536000";
+ public static final String VIEWS_HTTP_X_FRAME_OPTIONS_HEADER_VALUE_KEY = "views.http.x-frame-options";
+ public static final String VIEWS_HTTP_X_FRAME_OPTIONS_HEADER_VALUE_DEFAULT = "SAMEORIGIN";
+ public static final String VIEWS_HTTP_X_XSS_PROTECTION_HEADER_VALUE_KEY = "views.http.x-xss-protection";
+ public static final String VIEWS_HTTP_X_XSS_PROTECTION_HEADER_VALUE_DEFAULT = "1; mode=block";
+
private static final Logger LOG = LoggerFactory.getLogger(
Configuration.class);
@@ -1035,7 +1045,7 @@ public class Configuration {
}
/**
- * Get the value that should be set for the <code>Strict-Transport-Security</code> HTTP response header.
+ * Get the value that should be set for the <code>Strict-Transport-Security</code> HTTP response header for Ambari Server UI.
* <p/>
* By default this will be <code>max-age=31536000; includeSubDomains</code>. For example:
* <p/>
@@ -1052,7 +1062,7 @@ public class Configuration {
}
/**
- * Get the value that should be set for the <code>X-Frame-Options</code> HTTP response header.
+ * Get the value that should be set for the <code>X-Frame-Options</code> HTTP response header for Ambari Server UI.
* <p/>
* By default this will be <code>DENY</code>. For example:
* <p/>
@@ -1067,7 +1077,7 @@ public class Configuration {
}
/**
- * Get the value that should be set for the <code>X-XSS-Protection</code> HTTP response header.
+ * Get the value that should be set for the <code>X-XSS-Protection</code> HTTP response header for Ambari Server UI.
* <p/>
* By default this will be <code>1; mode=block</code>. For example:
* <p/>
@@ -1082,6 +1092,53 @@ public class Configuration {
}
/**
+ * Get the value that should be set for the <code>Strict-Transport-Security</code> HTTP response header for Ambari Views.
+ * <p/>
+ * By default this will be <code>max-age=31536000; includeSubDomains</code>. For example:
+ * <p/>
+ * <code>
+ * Strict-Transport-Security: max-age=31536000; includeSubDomains
+ * </code>
+ * <p/>
+ * This value may be ignored when {@link #getApiSSLAuthentication()} is <code>false</code>.
+ *
+ * @return the Strict-Transport-Security value - null or "" indicates that the value is not set
+ */
+ public String getViewsStrictTransportSecurityHTTPResponseHeader() {
+ return properties.getProperty(VIEWS_HTTP_STRICT_TRANSPORT_HEADER_VALUE_KEY, VIEWS_HTTP_STRICT_TRANSPORT_HEADER_VALUE_DEFAULT);
+ }
+
+ /**
+ * Get the value that should be set for the <code>X-Frame-Options</code> HTTP response header for Ambari Views.
+ * <p/>
+ * By default this will be <code>DENY</code>. For example:
+ * <p/>
+ * <code>
+ * X-Frame-Options: DENY
+ * </code>
+ *
+ * @return the X-Frame-Options value - null or "" indicates that the value is not set
+ */
+ public String getViewsXFrameOptionsHTTPResponseHeader() {
+ return properties.getProperty(VIEWS_HTTP_X_FRAME_OPTIONS_HEADER_VALUE_KEY, VIEWS_HTTP_X_FRAME_OPTIONS_HEADER_VALUE_DEFAULT);
+ }
+
+ /**
+ * Get the value that should be set for the <code>X-XSS-Protection</code> HTTP response header for Ambari Views.
+ * <p/>
+ * By default this will be <code>1; mode=block</code>. For example:
+ * <p/>
+ * <code>
+ * X-XSS-Protection: 1; mode=block
+ * </code>
+ *
+ * @return the X-XSS-Protection value - null or "" indicates that the value is not set
+ */
+ public String getViewsXXSSProtectionHTTPResponseHeader() {
+ return properties.getProperty(VIEWS_HTTP_X_XSS_PROTECTION_HEADER_VALUE_KEY, VIEWS_HTTP_X_XSS_PROTECTION_HEADER_VALUE_DEFAULT);
+ }
+
+ /**
* Check to see if two-way SSL auth should be used between server and agents
* or not
*
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/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 1265b6a..b33d977 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
@@ -20,7 +20,7 @@ package org.apache.ambari.server.controller;
import org.apache.ambari.server.api.AmbariPersistFilter;
import org.apache.ambari.server.orm.entities.ViewEntity;
import org.apache.ambari.server.orm.entities.ViewInstanceEntity;
-import org.apache.ambari.server.security.SecurityHeaderFilter;
+import org.apache.ambari.server.security.AmbariViewsSecurityHeaderFilter;
import org.apache.ambari.server.view.ViewContextImpl;
import org.apache.ambari.server.view.ViewInstanceHandlerList;
import org.apache.ambari.server.view.ViewRegistry;
@@ -95,10 +95,10 @@ public class AmbariHandlerList extends HandlerCollection implements ViewInstance
DelegatingFilterProxy springSecurityFilter;
/**
- * The security header filter - conditionlly adds security-related headers to the HTTP response.
+ * The security header filter - conditionally adds security-related headers to the HTTP response for Ambari Views requests.
*/
@Inject
- SecurityHeaderFilter securityHeaderFilter;
+ AmbariViewsSecurityHeaderFilter ambariViewsSecurityHeaderFilter;
/**
* Mapping of view instance entities to handlers.
@@ -241,7 +241,7 @@ public class AmbariHandlerList extends HandlerCollection implements ViewInstance
webAppContext.setClassLoader(viewInstanceDefinition.getViewEntity().getClassLoader());
webAppContext.setAttribute(ViewContext.CONTEXT_ATTRIBUTE, new ViewContextImpl(viewInstanceDefinition, viewRegistry));
webAppContext.setSessionHandler(new SharedSessionHandler(sessionManager));
- webAppContext.addFilter(new FilterHolder(securityHeaderFilter), "/*", AmbariServer.DISPATCHER_TYPES);
+ webAppContext.addFilter(new FilterHolder(ambariViewsSecurityHeaderFilter), "/*", AmbariServer.DISPATCHER_TYPES);
webAppContext.addFilter(new FilterHolder(persistFilter), "/*", AmbariServer.DISPATCHER_TYPES);
webAppContext.addFilter(new FilterHolder(springSecurityFilter), "/*", AmbariServer.DISPATCHER_TYPES);
webAppContext.setAllowNullPathInfo(true);
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/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 5974494..8f3869f 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
@@ -80,9 +80,9 @@ import org.apache.ambari.server.orm.entities.MetainfoEntity;
import org.apache.ambari.server.resources.ResourceManager;
import org.apache.ambari.server.resources.api.rest.GetResource;
import org.apache.ambari.server.scheduler.ExecutionScheduleManager;
+import org.apache.ambari.server.security.AmbariServerSecurityHeaderFilter;
import org.apache.ambari.server.security.CertificateManager;
import org.apache.ambari.server.security.SecurityFilter;
-import org.apache.ambari.server.security.SecurityHeaderFilter;
import org.apache.ambari.server.security.authorization.AmbariAuthorizationFilter;
import org.apache.ambari.server.security.authorization.AmbariLdapAuthenticationProvider;
import org.apache.ambari.server.security.authorization.AmbariLocalUserDetailsService;
@@ -290,7 +290,7 @@ public class AmbariServer {
rootServlet.setInitOrder(1);
// Conditionally adds security-related headers to all HTTP responses.
- root.addFilter(new FilterHolder(injector.getInstance(SecurityHeaderFilter.class)), "/*", DISPATCHER_TYPES);
+ root.addFilter(new FilterHolder(injector.getInstance(AmbariServerSecurityHeaderFilter.class)), "/*", DISPATCHER_TYPES);
//session-per-request strategy for api and agents
root.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/api/*", DISPATCHER_TYPES);
// root.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/proxy/*", DISPATCHER_TYPES);
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/ambari-server/src/main/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilter.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilter.java
new file mode 100644
index 0000000..36f691c
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilter.java
@@ -0,0 +1,143 @@
+/*
+ * 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 org.apache.ambari.server.security;
+
+import com.google.inject.Inject;
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * AbstractSecurityHeaderFilter is an abstract class used to help add security-related headers to
+ * HTTP responses.
+ * <p/>
+ * This class is to be implemented to set the values for the following headers:
+ * <ol>
+ * <li>Strict-Transport-Security</li>
+ * <li>X-Frame-Options</li>
+ * <li>X-XSS-Protection</li>
+ * </ol>
+ * <p/>
+ * If the value for a particular header item is empty (or null) that header will not be added to the
+ * set of response headers.
+ */
+public abstract class AbstractSecurityHeaderFilter implements Filter {
+ protected final static String STRICT_TRANSPORT_HEADER = "Strict-Transport-Security";
+ protected final static String X_FRAME_OPTIONS_HEADER = "X-Frame-Options";
+ protected final static String X_XSS_PROTECTION_HEADER = "X-XSS-Protection";
+
+ /**
+ * The logger.
+ */
+ private final static Logger LOG = LoggerFactory.getLogger(AbstractSecurityHeaderFilter.class);
+ /**
+ * The Configuration object used to determine how Ambari is configured
+ */
+ @Inject
+ private Configuration configuration;
+
+ /**
+ * Indicates whether Ambari is configured for SSL (true) or not (false). By default true is assumed
+ * since preparing for more security will not hurt and is better than not assuming SSL is enabled
+ * when it is.
+ */
+ private boolean sslEnabled = true;
+ /**
+ * The value for the Strict-Transport-Security HTTP response header.
+ */
+ private String strictTransportSecurity = Configuration.HTTP_STRICT_TRANSPORT_HEADER_VALUE_DEFAULT;
+ /**
+ * The value for the X-Frame-Options HTTP response header.
+ */
+ private String xFrameOptionsHeader = Configuration.HTTP_X_FRAME_OPTIONS_HEADER_VALUE_DEFAULT;
+ /**
+ * The value for the X-XSS-Protection HTTP response header.
+ */
+ private String xXSSProtectionHeader = Configuration.HTTP_X_XSS_PROTECTION_HEADER_VALUE_DEFAULT;
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ LOG.debug("Initializing {}", this.getClass().getName());
+
+ if (configuration == null) {
+ LOG.warn("The Ambari configuration object is not available, all default options will be assumed.");
+ } else {
+ processConfig(configuration);
+ }
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+
+ if (servletResponse instanceof HttpServletResponse) {
+ HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
+ // Conditionally set the Strict-Transport-Security HTTP response header if SSL is enabled and
+ // a value is supplied
+ if (sslEnabled && !StringUtils.isEmpty(strictTransportSecurity)) {
+ httpServletResponse.setHeader(STRICT_TRANSPORT_HEADER, strictTransportSecurity);
+ }
+
+ // Conditionally set the X-Frame-Options HTTP response header if a value is supplied
+ if (!StringUtils.isEmpty(xFrameOptionsHeader)) {
+ httpServletResponse.setHeader(X_FRAME_OPTIONS_HEADER, xFrameOptionsHeader);
+ }
+
+ // Conditionally set the X-XSS-Protection HTTP response header if a value is supplied
+ if (!StringUtils.isEmpty(xXSSProtectionHeader)) {
+ httpServletResponse.setHeader(X_XSS_PROTECTION_HEADER, xXSSProtectionHeader);
+ }
+ }
+
+ filterChain.doFilter(servletRequest, servletResponse);
+ }
+
+ @Override
+ public void destroy() {
+ LOG.debug("Destroying {}", this.getClass().getName());
+ }
+
+ protected abstract void processConfig(Configuration configuration);
+
+
+ protected void setSslEnabled(boolean sslEnabled) {
+ this.sslEnabled = sslEnabled;
+ }
+
+ protected void setStrictTransportSecurity(String strictTransportSecurity) {
+ this.strictTransportSecurity = strictTransportSecurity;
+ }
+
+ protected void setxFrameOptionsHeader(String xFrameOptionsHeader) {
+ this.xFrameOptionsHeader = xFrameOptionsHeader;
+ }
+
+ protected void setxXSSProtectionHeader(String xXSSProtectionHeader) {
+ this.xXSSProtectionHeader = xXSSProtectionHeader;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariServerSecurityHeaderFilter.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariServerSecurityHeaderFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariServerSecurityHeaderFilter.java
new file mode 100644
index 0000000..86c28ea
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariServerSecurityHeaderFilter.java
@@ -0,0 +1,37 @@
+/*
+ * 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 org.apache.ambari.server.security;
+
+import com.google.inject.Singleton;
+import org.apache.ambari.server.configuration.Configuration;
+
+/**
+ * AmbariServerSecurityHeaderFilter adds security-related headers to HTTP response messages for Ambari Server UI
+ */
+@Singleton
+public class AmbariServerSecurityHeaderFilter extends AbstractSecurityHeaderFilter {
+
+ @Override
+ protected void processConfig(Configuration configuration) {
+ setSslEnabled(configuration.getApiSSLAuthentication());
+ setStrictTransportSecurity(configuration.getStrictTransportSecurityHTTPResponseHeader());
+ setxFrameOptionsHeader(configuration.getXFrameOptionsHTTPResponseHeader());
+ setxXSSProtectionHeader(configuration.getXXSSProtectionHTTPResponseHeader());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariViewsSecurityHeaderFilter.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariViewsSecurityHeaderFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariViewsSecurityHeaderFilter.java
new file mode 100644
index 0000000..63137fb
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariViewsSecurityHeaderFilter.java
@@ -0,0 +1,37 @@
+/*
+ * 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 org.apache.ambari.server.security;
+
+import com.google.inject.Singleton;
+import org.apache.ambari.server.configuration.Configuration;
+
+/**
+ * AmbariViewsSecurityHeaderFilter adds security-related headers to HTTP response messages for Ambari Views
+ */
+@Singleton
+public class AmbariViewsSecurityHeaderFilter extends AbstractSecurityHeaderFilter {
+
+ @Override
+ protected void processConfig(Configuration configuration) {
+ setSslEnabled(configuration.getApiSSLAuthentication());
+ setStrictTransportSecurity(configuration.getViewsStrictTransportSecurityHTTPResponseHeader());
+ setxFrameOptionsHeader(configuration.getViewsXFrameOptionsHTTPResponseHeader());
+ setxXSSProtectionHeader(configuration.getViewsXXSSProtectionHTTPResponseHeader());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityHeaderFilter.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityHeaderFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityHeaderFilter.java
deleted file mode 100644
index a7479af..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityHeaderFilter.java
+++ /dev/null
@@ -1,121 +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 org.apache.ambari.server.security;
-
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import org.apache.ambari.server.configuration.Configuration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-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.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * SecurityHeaderFilter adds security-related headers to HTTP response messages
- */
-@Singleton
-public class SecurityHeaderFilter implements Filter {
- /**
- * The logger.
- */
- private final static Logger LOG = LoggerFactory.getLogger(SecurityHeaderFilter.class);
-
- protected final static String STRICT_TRANSPORT_HEADER = "Strict-Transport-Security";
- protected final static String X_FRAME_OPTIONS_HEADER = "X-Frame-Options";
- protected final static String X_XSS_PROTECTION_HEADER = "X-XSS-Protection";
-
- /**
- * The Configuration object used to determing how Ambari is configured
- */
- @Inject
- private Configuration configuration;
-
- /**
- * Indicates whether Ambari is configured for SSL (true) or not (false). By default true is assumed
- * since preparing for more security will not hurt and is better than not assuming SSL is enabled
- * when it is.
- */
- private boolean sslEnabled = true;
-
- /**
- * The value for the Strict-Transport-Security HTTP response header.
- */
- private String strictTransportSecurity = Configuration.HTTP_STRICT_TRANSPORT_HEADER_VALUE_DEFAULT;
-
- /**
- * The value for the X-Frame-Options HTTP response header.
- */
- private String xFrameOptionsHeader = Configuration.HTTP_X_FRAME_OPTIONS_HEADER_VALUE_DEFAULT;
-
- /**
- * The value for the X-XSS-Protection HTTP response header.
- */
- private String xXSSProtectionHeader = Configuration.HTTP_X_XSS_PROTECTION_HEADER_VALUE_DEFAULT;
-
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- LOG.debug("Initializing {}", this.getClass().getName());
-
- if (configuration == null) {
- LOG.warn("The Ambari configuration object is not available, all default options will be assumed.");
- } else {
- sslEnabled = configuration.getApiSSLAuthentication();
- strictTransportSecurity = configuration.getStrictTransportSecurityHTTPResponseHeader();
- xFrameOptionsHeader = configuration.getXFrameOptionsHTTPResponseHeader();
- xXSSProtectionHeader = configuration.getXXSSProtectionHTTPResponseHeader();
- }
- }
-
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
-
- if (servletResponse instanceof HttpServletResponse) {
- HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
- // Conditionally set the Strict-Transport-Security HTTP response header if SSL is enabled and
- // a value is supplied
- if (sslEnabled && (strictTransportSecurity != null) && !strictTransportSecurity.isEmpty()) {
- httpServletResponse.setHeader(STRICT_TRANSPORT_HEADER, strictTransportSecurity);
- }
-
- // Conditionally set the X-Frame-Options HTTP response header if a value is supplied
- if ((xFrameOptionsHeader != null) && !xFrameOptionsHeader.isEmpty()) {
- httpServletResponse.setHeader(X_FRAME_OPTIONS_HEADER, xFrameOptionsHeader);
- }
-
- // Conditionally set the X-XSS-Protection HTTP response header if a value is supplied
- if ((xXSSProtectionHeader != null) && !xXSSProtectionHeader.isEmpty()) {
- httpServletResponse.setHeader(X_XSS_PROTECTION_HEADER, xXSSProtectionHeader);
- }
- }
-
- filterChain.doFilter(servletRequest, servletResponse);
- }
-
- @Override
- public void destroy() {
- LOG.debug("Destroying {}", this.getClass().getName());
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
index a0cb8d0..2e2cc45 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
@@ -22,7 +22,7 @@ import org.apache.ambari.server.api.AmbariPersistFilter;
import org.apache.ambari.server.orm.entities.ViewEntity;
import org.apache.ambari.server.orm.entities.ViewInstanceEntity;
import org.apache.ambari.server.orm.entities.ViewInstanceEntityTest;
-import org.apache.ambari.server.security.SecurityHeaderFilter;
+import org.apache.ambari.server.security.AmbariViewsSecurityHeaderFilter;
import org.apache.ambari.server.view.ViewRegistry;
import org.easymock.Capture;
import org.eclipse.jetty.server.Handler;
@@ -52,7 +52,7 @@ import static org.easymock.EasyMock.verify;
*/
public class AmbariHandlerListTest {
- private final SecurityHeaderFilter securityHeaderFilter = createNiceMock(SecurityHeaderFilter.class);
+ private final AmbariViewsSecurityHeaderFilter ambariViewsSecurityHeaderFilter = createNiceMock(AmbariViewsSecurityHeaderFilter.class);
private final AmbariPersistFilter persistFilter = createNiceMock(AmbariPersistFilter.class);
private final DelegatingFilterProxy springSecurityFilter = createNiceMock(DelegatingFilterProxy.class);
@@ -87,7 +87,7 @@ public class AmbariHandlerListTest {
Assert.assertTrue(handlers.contains(handler));
- Assert.assertEquals(securityHeaderFilter, securityHeaderFilterCapture.getValue().getFilter());
+ Assert.assertEquals(ambariViewsSecurityHeaderFilter, securityHeaderFilterCapture.getValue().getFilter());
Assert.assertEquals(persistFilter, persistFilterCapture.getValue().getFilter());
Assert.assertEquals(springSecurityFilter, securityFilterCapture.getValue().getFilter());
@@ -161,7 +161,7 @@ public class AmbariHandlerListTest {
AmbariHandlerList handlerList = new AmbariHandlerList();
handlerList.webAppContextProvider = new HandlerProvider(handler);
- handlerList.securityHeaderFilter = securityHeaderFilter;
+ handlerList.ambariViewsSecurityHeaderFilter = ambariViewsSecurityHeaderFilter;
handlerList.persistFilter = persistFilter;
handlerList.springSecurityFilter = springSecurityFilter;
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/ambari-server/src/test/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilterTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilterTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilterTest.java
new file mode 100644
index 0000000..3481092
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilterTest.java
@@ -0,0 +1,329 @@
+/*
+ * 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 org.apache.ambari.server.security;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import junit.framework.Assert;
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.state.stack.OsFamily;
+import org.easymock.EasyMockSupport;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.easymock.EasyMock.expectLastCall;
+
+public abstract class AbstractSecurityHeaderFilterTest extends EasyMockSupport {
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ private final Class<? extends AbstractSecurityHeaderFilter> filterClass;
+ private final Map<String, String> propertyNameMap;
+ private final Map<String, String> defatulPropertyValueMap;
+
+ protected AbstractSecurityHeaderFilterTest(Class<? extends AbstractSecurityHeaderFilter> filterClass, Map<String, String> propertyNameMap, Map<String, String> defatulPropertyValueMap) {
+ this.filterClass = filterClass;
+ this.propertyNameMap = propertyNameMap;
+ this.defatulPropertyValueMap = defatulPropertyValueMap;
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ temporaryFolder.create();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ temporaryFolder.delete();
+ }
+
+ @Test
+ public void testDoFilter_DefaultValuesNoSSL() throws Exception {
+ Injector injector = Guice.createInjector(new AbstractModule() {
+
+ @Override
+ protected void configure() {
+ Properties properties = new Properties();
+ properties.setProperty(Configuration.API_USE_SSL, "false");
+
+ bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+ bind(Configuration.class).toInstance(new Configuration(properties));
+ }
+ });
+
+ FilterConfig filterConfig = createNiceMock(FilterConfig.class);
+
+ HttpServletRequest servletRequest = createStrictMock(HttpServletRequest.class);
+
+ HttpServletResponse servletResponse = createStrictMock(HttpServletResponse.class);
+ servletResponse.setHeader(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER, defatulPropertyValueMap.get(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER));
+ expectLastCall().once();
+ servletResponse.setHeader(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER, defatulPropertyValueMap.get(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER));
+ expectLastCall().once();
+
+ FilterChain filterChain = createStrictMock(FilterChain.class);
+ filterChain.doFilter(servletRequest, servletResponse);
+ expectLastCall().once();
+
+ replayAll();
+
+ AbstractSecurityHeaderFilter securityFilter = injector.getInstance(filterClass);
+ Assert.assertNotNull(securityFilter);
+
+ securityFilter.init(filterConfig);
+ securityFilter.doFilter(servletRequest, servletResponse, filterChain);
+
+ verifyAll();
+ }
+
+ @Test
+ public void testDoFilter_DefaultValuesSSL() throws Exception {
+ final File httpPassFile = temporaryFolder.newFile();
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+
+ @Override
+ protected void configure() {
+ Properties properties = new Properties();
+ properties.setProperty(Configuration.API_USE_SSL, "true");
+ properties.setProperty(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME_KEY, httpPassFile.getParent());
+ properties.setProperty(Configuration.CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY, httpPassFile.getName());
+
+ bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+ bind(Configuration.class).toInstance(new Configuration(properties));
+ }
+ });
+
+ FilterConfig filterConfig = createNiceMock(FilterConfig.class);
+
+ HttpServletRequest servletRequest = createStrictMock(HttpServletRequest.class);
+
+ HttpServletResponse servletResponse = createStrictMock(HttpServletResponse.class);
+ servletResponse.setHeader(AbstractSecurityHeaderFilter.STRICT_TRANSPORT_HEADER, defatulPropertyValueMap.get(AbstractSecurityHeaderFilter.STRICT_TRANSPORT_HEADER));
+ expectLastCall().once();
+ servletResponse.setHeader(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER, defatulPropertyValueMap.get(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER));
+ expectLastCall().once();
+ servletResponse.setHeader(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER, defatulPropertyValueMap.get(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER));
+ expectLastCall().once();
+
+ FilterChain filterChain = createStrictMock(FilterChain.class);
+ filterChain.doFilter(servletRequest, servletResponse);
+ expectLastCall().once();
+
+ replayAll();
+
+ AbstractSecurityHeaderFilter securityFilter = injector.getInstance(filterClass);
+ Assert.assertNotNull(securityFilter);
+
+ securityFilter.init(filterConfig);
+ securityFilter.doFilter(servletRequest, servletResponse, filterChain);
+
+ verifyAll();
+ }
+
+ @Test
+ public void testDoFilter_CustomValuesNoSSL() throws Exception {
+ final File httpPassFile = temporaryFolder.newFile();
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+
+ @Override
+ protected void configure() {
+ Properties properties = new Properties();
+ properties.setProperty(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME_KEY, httpPassFile.getParent());
+ properties.setProperty(Configuration.CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY, httpPassFile.getName());
+ properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.STRICT_TRANSPORT_HEADER), "custom1");
+ properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER), "custom2");
+ properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER), "custom3");
+
+ bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+ bind(Configuration.class).toInstance(new Configuration(properties));
+ }
+ });
+
+ FilterConfig filterConfig = createNiceMock(FilterConfig.class);
+
+ HttpServletRequest servletRequest = createStrictMock(HttpServletRequest.class);
+
+ HttpServletResponse servletResponse = createStrictMock(HttpServletResponse.class);
+ servletResponse.setHeader(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER, "custom2");
+ expectLastCall().once();
+ servletResponse.setHeader(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER, "custom3");
+ expectLastCall().once();
+
+ FilterChain filterChain = createStrictMock(FilterChain.class);
+ filterChain.doFilter(servletRequest, servletResponse);
+ expectLastCall().once();
+
+ replayAll();
+
+ AbstractSecurityHeaderFilter securityFilter = injector.getInstance(filterClass);
+ Assert.assertNotNull(securityFilter);
+
+ securityFilter.init(filterConfig);
+ securityFilter.doFilter(servletRequest, servletResponse, filterChain);
+
+ verifyAll();
+ }
+
+ @Test
+ public void testDoFilter_CustomValuesSSL() throws Exception {
+ final File httpPassFile = temporaryFolder.newFile();
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+
+ @Override
+ protected void configure() {
+ Properties properties = new Properties();
+ properties.setProperty(Configuration.API_USE_SSL, "true");
+ properties.setProperty(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME_KEY, httpPassFile.getParent());
+ properties.setProperty(Configuration.CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY, httpPassFile.getName());
+ properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.STRICT_TRANSPORT_HEADER), "custom1");
+ properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER), "custom2");
+ properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER), "custom3");
+
+ bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+ bind(Configuration.class).toInstance(new Configuration(properties));
+ }
+ });
+
+ FilterConfig filterConfig = createNiceMock(FilterConfig.class);
+
+ HttpServletRequest servletRequest = createStrictMock(HttpServletRequest.class);
+
+ HttpServletResponse servletResponse = createStrictMock(HttpServletResponse.class);
+ servletResponse.setHeader(AbstractSecurityHeaderFilter.STRICT_TRANSPORT_HEADER, "custom1");
+ expectLastCall().once();
+ servletResponse.setHeader(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER, "custom2");
+ expectLastCall().once();
+ servletResponse.setHeader(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER, "custom3");
+ expectLastCall().once();
+
+ FilterChain filterChain = createStrictMock(FilterChain.class);
+ filterChain.doFilter(servletRequest, servletResponse);
+ expectLastCall().once();
+
+ replayAll();
+
+ AbstractSecurityHeaderFilter securityFilter = injector.getInstance(filterClass);
+ Assert.assertNotNull(securityFilter);
+
+ securityFilter.init(filterConfig);
+ securityFilter.doFilter(servletRequest, servletResponse, filterChain);
+
+ verifyAll();
+ }
+
+ @Test
+ public void testDoFilter_EmptyValuesNoSSL() throws Exception {
+ final File httpPassFile = temporaryFolder.newFile();
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+
+ @Override
+ protected void configure() {
+ Properties properties = new Properties();
+ properties.setProperty(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME_KEY, httpPassFile.getParent());
+ properties.setProperty(Configuration.CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY, httpPassFile.getName());
+ properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.STRICT_TRANSPORT_HEADER), "");
+ properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER), "");
+ properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER), "");
+
+ bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+ bind(Configuration.class).toInstance(new Configuration(properties));
+ }
+ });
+
+ FilterConfig filterConfig = createNiceMock(FilterConfig.class);
+
+ HttpServletRequest servletRequest = createStrictMock(HttpServletRequest.class);
+
+ HttpServletResponse servletResponse = createStrictMock(HttpServletResponse.class);
+
+ FilterChain filterChain = createStrictMock(FilterChain.class);
+ filterChain.doFilter(servletRequest, servletResponse);
+ expectLastCall().once();
+
+ replayAll();
+
+ AbstractSecurityHeaderFilter securityFilter = injector.getInstance(filterClass);
+ Assert.assertNotNull(securityFilter);
+
+ securityFilter.init(filterConfig);
+ securityFilter.doFilter(servletRequest, servletResponse, filterChain);
+
+ verifyAll();
+ }
+
+ @Test
+ public void testDoFilter_EmptyValuesSSL() throws Exception {
+ final File httpPassFile = temporaryFolder.newFile();
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+
+ @Override
+ protected void configure() {
+ Properties properties = new Properties();
+ properties.setProperty(Configuration.API_USE_SSL, "true");
+ properties.setProperty(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME_KEY, httpPassFile.getParent());
+ properties.setProperty(Configuration.CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY, httpPassFile.getName());
+ properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.STRICT_TRANSPORT_HEADER), "");
+ properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER), "");
+ properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER), "");
+
+ bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+ bind(Configuration.class).toInstance(new Configuration(properties));
+ }
+ });
+
+ FilterConfig filterConfig = createNiceMock(FilterConfig.class);
+
+ HttpServletRequest servletRequest = createStrictMock(HttpServletRequest.class);
+
+ HttpServletResponse servletResponse = createStrictMock(HttpServletResponse.class);
+
+ FilterChain filterChain = createStrictMock(FilterChain.class);
+ filterChain.doFilter(servletRequest, servletResponse);
+ expectLastCall().once();
+
+ replayAll();
+
+ AbstractSecurityHeaderFilter securityFilter = injector.getInstance(filterClass);
+ Assert.assertNotNull(securityFilter);
+
+ securityFilter.init(filterConfig);
+ securityFilter.doFilter(servletRequest, servletResponse, filterChain);
+
+ verifyAll();
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariServerSecurityHeaderFilterTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariServerSecurityHeaderFilterTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariServerSecurityHeaderFilterTest.java
new file mode 100644
index 0000000..0e3313e
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariServerSecurityHeaderFilterTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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 org.apache.ambari.server.security;
+
+import org.apache.ambari.server.configuration.Configuration;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class AmbariServerSecurityHeaderFilterTest extends AbstractSecurityHeaderFilterTest {
+
+ private static final Map<String, String> PROPERTY_NAME_MAP;
+ private static final Map<String, String> DEFAULT_PROPERTY_VALUE_MAP;
+
+ static {
+
+ Map<String, String> map;
+ map = new HashMap<String, String>();
+ map.put(AbstractSecurityHeaderFilter.STRICT_TRANSPORT_HEADER, Configuration.HTTP_STRICT_TRANSPORT_HEADER_VALUE_KEY);
+ map.put(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER, Configuration.HTTP_X_FRAME_OPTIONS_HEADER_VALUE_KEY);
+ map.put(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER, Configuration.HTTP_X_XSS_PROTECTION_HEADER_VALUE_KEY);
+ PROPERTY_NAME_MAP = Collections.unmodifiableMap(map);
+
+ map = new HashMap<String, String>();
+ map.put(AbstractSecurityHeaderFilter.STRICT_TRANSPORT_HEADER, Configuration.HTTP_STRICT_TRANSPORT_HEADER_VALUE_DEFAULT);
+ map.put(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER, Configuration.HTTP_X_FRAME_OPTIONS_HEADER_VALUE_DEFAULT);
+ map.put(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER, Configuration.HTTP_X_XSS_PROTECTION_HEADER_VALUE_DEFAULT);
+ DEFAULT_PROPERTY_VALUE_MAP = Collections.unmodifiableMap(map);
+ }
+
+ public AmbariServerSecurityHeaderFilterTest() {
+ super(AmbariServerSecurityHeaderFilter.class, PROPERTY_NAME_MAP, DEFAULT_PROPERTY_VALUE_MAP);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariViewsSecurityHeaderFilterTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariViewsSecurityHeaderFilterTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariViewsSecurityHeaderFilterTest.java
new file mode 100644
index 0000000..d760962
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariViewsSecurityHeaderFilterTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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 org.apache.ambari.server.security;
+
+import org.apache.ambari.server.configuration.Configuration;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class AmbariViewsSecurityHeaderFilterTest extends AbstractSecurityHeaderFilterTest {
+
+ private static final Map<String, String> PROPERTY_NAME_MAP;
+ private static final Map<String, String> DEFAULT_PROPERTY_VALUE_MAP;
+
+ static {
+
+ Map<String, String> map;
+
+ map = new HashMap<String, String>();
+ map.put(AbstractSecurityHeaderFilter.STRICT_TRANSPORT_HEADER, Configuration.VIEWS_HTTP_STRICT_TRANSPORT_HEADER_VALUE_KEY);
+ map.put(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER, Configuration.VIEWS_HTTP_X_FRAME_OPTIONS_HEADER_VALUE_KEY);
+ map.put(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER, Configuration.VIEWS_HTTP_X_XSS_PROTECTION_HEADER_VALUE_KEY);
+ PROPERTY_NAME_MAP = Collections.unmodifiableMap(map);
+
+ map = new HashMap<String, String>();
+ map.put(AbstractSecurityHeaderFilter.STRICT_TRANSPORT_HEADER, Configuration.VIEWS_HTTP_STRICT_TRANSPORT_HEADER_VALUE_DEFAULT);
+ map.put(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER, Configuration.VIEWS_HTTP_X_FRAME_OPTIONS_HEADER_VALUE_DEFAULT);
+ map.put(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER, Configuration.VIEWS_HTTP_X_XSS_PROTECTION_HEADER_VALUE_DEFAULT);
+ DEFAULT_PROPERTY_VALUE_MAP = Collections.unmodifiableMap(map);
+ }
+
+ public AmbariViewsSecurityHeaderFilterTest() {
+ super(AmbariViewsSecurityHeaderFilter.class, PROPERTY_NAME_MAP, DEFAULT_PROPERTY_VALUE_MAP);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/31542ae3/ambari-server/src/test/java/org/apache/ambari/server/security/SecurityHeaderFilterTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/SecurityHeaderFilterTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/SecurityHeaderFilterTest.java
deleted file mode 100644
index 5e8d2af..0000000
--- a/ambari-server/src/test/java/org/apache/ambari/server/security/SecurityHeaderFilterTest.java
+++ /dev/null
@@ -1,318 +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 org.apache.ambari.server.security;
-
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import junit.framework.Assert;
-import org.apache.ambari.server.configuration.Configuration;
-import org.apache.ambari.server.state.stack.OsFamily;
-import org.easymock.EasyMockSupport;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import java.io.File;
-import java.util.Properties;
-
-import static org.easymock.EasyMock.expectLastCall;
-
-public class SecurityHeaderFilterTest extends EasyMockSupport {
-
- @Rule
- public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
- @Before
- public void setUp() throws Exception {
- temporaryFolder.create();
- }
-
- @After
- public void tearDown() throws Exception {
- temporaryFolder.delete();
- }
-
- @Test
- public void testDoFilter_DefaultValuesNoSSL() throws Exception {
- Injector injector = Guice.createInjector(new AbstractModule() {
-
- @Override
- protected void configure() {
- Properties properties = new Properties();
- properties.setProperty(Configuration.API_USE_SSL, "false");
-
- bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
- bind(Configuration.class).toInstance(new Configuration(properties));
- }
- });
-
- FilterConfig filterConfig = createNiceMock(FilterConfig.class);
-
- HttpServletRequest servletRequest = createStrictMock(HttpServletRequest.class);
-
- HttpServletResponse servletResponse = createStrictMock(HttpServletResponse.class);
- servletResponse.setHeader(SecurityHeaderFilter.X_FRAME_OPTIONS_HEADER, Configuration.HTTP_X_FRAME_OPTIONS_HEADER_VALUE_DEFAULT);
- expectLastCall().once();
- servletResponse.setHeader(SecurityHeaderFilter.X_XSS_PROTECTION_HEADER, Configuration.HTTP_X_XSS_PROTECTION_HEADER_VALUE_DEFAULT);
- expectLastCall().once();
-
- FilterChain filterChain = createStrictMock(FilterChain.class);
- filterChain.doFilter(servletRequest, servletResponse);
- expectLastCall().once();
-
- replayAll();
-
- SecurityHeaderFilter securityFilter = injector.getInstance(SecurityHeaderFilter.class);
- Assert.assertNotNull(securityFilter);
-
- securityFilter.init(filterConfig);
- securityFilter.doFilter(servletRequest, servletResponse, filterChain);
-
- verifyAll();
- }
-
- @Test
- public void testDoFilter_DefaultValuesSSL() throws Exception {
- final File httpPassFile = temporaryFolder.newFile();
-
- Injector injector = Guice.createInjector(new AbstractModule() {
-
- @Override
- protected void configure() {
- Properties properties = new Properties();
- properties.setProperty(Configuration.API_USE_SSL, "true");
- properties.setProperty(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME_KEY, httpPassFile.getParent());
- properties.setProperty(Configuration.CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY, httpPassFile.getName());
-
- bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
- bind(Configuration.class).toInstance(new Configuration(properties));
- }
- });
-
- FilterConfig filterConfig = createNiceMock(FilterConfig.class);
-
- HttpServletRequest servletRequest = createStrictMock(HttpServletRequest.class);
-
- HttpServletResponse servletResponse = createStrictMock(HttpServletResponse.class);
- servletResponse.setHeader(SecurityHeaderFilter.STRICT_TRANSPORT_HEADER, Configuration.HTTP_STRICT_TRANSPORT_HEADER_VALUE_DEFAULT);
- expectLastCall().once();
- servletResponse.setHeader(SecurityHeaderFilter.X_FRAME_OPTIONS_HEADER, Configuration.HTTP_X_FRAME_OPTIONS_HEADER_VALUE_DEFAULT);
- expectLastCall().once();
- servletResponse.setHeader(SecurityHeaderFilter.X_XSS_PROTECTION_HEADER, Configuration.HTTP_X_XSS_PROTECTION_HEADER_VALUE_DEFAULT);
- expectLastCall().once();
-
- FilterChain filterChain = createStrictMock(FilterChain.class);
- filterChain.doFilter(servletRequest, servletResponse);
- expectLastCall().once();
-
- replayAll();
-
- SecurityHeaderFilter securityFilter = injector.getInstance(SecurityHeaderFilter.class);
- Assert.assertNotNull(securityFilter);
-
- securityFilter.init(filterConfig);
- securityFilter.doFilter(servletRequest, servletResponse, filterChain);
-
- verifyAll();
- }
-
- @Test
- public void testDoFilter_CustomValuesNoSSL() throws Exception {
- final File httpPassFile = temporaryFolder.newFile();
-
- Injector injector = Guice.createInjector(new AbstractModule() {
-
- @Override
- protected void configure() {
- Properties properties = new Properties();
- properties.setProperty(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME_KEY, httpPassFile.getParent());
- properties.setProperty(Configuration.CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY, httpPassFile.getName());
- properties.setProperty(Configuration.HTTP_STRICT_TRANSPORT_HEADER_VALUE_KEY, "custom1");
- properties.setProperty(Configuration.HTTP_X_FRAME_OPTIONS_HEADER_VALUE_KEY, "custom2");
- properties.setProperty(Configuration.HTTP_X_XSS_PROTECTION_HEADER_VALUE_KEY, "custom3");
-
- bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
- bind(Configuration.class).toInstance(new Configuration(properties));
- }
- });
-
- FilterConfig filterConfig = createNiceMock(FilterConfig.class);
-
- HttpServletRequest servletRequest = createStrictMock(HttpServletRequest.class);
-
- HttpServletResponse servletResponse = createStrictMock(HttpServletResponse.class);
- servletResponse.setHeader(SecurityHeaderFilter.X_FRAME_OPTIONS_HEADER, "custom2");
- expectLastCall().once();
- servletResponse.setHeader(SecurityHeaderFilter.X_XSS_PROTECTION_HEADER, "custom3");
- expectLastCall().once();
-
- FilterChain filterChain = createStrictMock(FilterChain.class);
- filterChain.doFilter(servletRequest, servletResponse);
- expectLastCall().once();
-
- replayAll();
-
- SecurityHeaderFilter securityFilter = injector.getInstance(SecurityHeaderFilter.class);
- Assert.assertNotNull(securityFilter);
-
- securityFilter.init(filterConfig);
- securityFilter.doFilter(servletRequest, servletResponse, filterChain);
-
- verifyAll();
- }
-
- @Test
- public void testDoFilter_CustomValuesSSL() throws Exception {
- final File httpPassFile = temporaryFolder.newFile();
-
- Injector injector = Guice.createInjector(new AbstractModule() {
-
- @Override
- protected void configure() {
- Properties properties = new Properties();
- properties.setProperty(Configuration.API_USE_SSL, "true");
- properties.setProperty(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME_KEY, httpPassFile.getParent());
- properties.setProperty(Configuration.CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY, httpPassFile.getName());
- properties.setProperty(Configuration.HTTP_STRICT_TRANSPORT_HEADER_VALUE_KEY, "custom1");
- properties.setProperty(Configuration.HTTP_X_FRAME_OPTIONS_HEADER_VALUE_KEY, "custom2");
- properties.setProperty(Configuration.HTTP_X_XSS_PROTECTION_HEADER_VALUE_KEY, "custom3");
-
- bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
- bind(Configuration.class).toInstance(new Configuration(properties));
- }
- });
-
- FilterConfig filterConfig = createNiceMock(FilterConfig.class);
-
- HttpServletRequest servletRequest = createStrictMock(HttpServletRequest.class);
-
- HttpServletResponse servletResponse = createStrictMock(HttpServletResponse.class);
- servletResponse.setHeader(SecurityHeaderFilter.STRICT_TRANSPORT_HEADER, "custom1");
- expectLastCall().once();
- servletResponse.setHeader(SecurityHeaderFilter.X_FRAME_OPTIONS_HEADER, "custom2");
- expectLastCall().once();
- servletResponse.setHeader(SecurityHeaderFilter.X_XSS_PROTECTION_HEADER, "custom3");
- expectLastCall().once();
-
- FilterChain filterChain = createStrictMock(FilterChain.class);
- filterChain.doFilter(servletRequest, servletResponse);
- expectLastCall().once();
-
- replayAll();
-
- SecurityHeaderFilter securityFilter = injector.getInstance(SecurityHeaderFilter.class);
- Assert.assertNotNull(securityFilter);
-
- securityFilter.init(filterConfig);
- securityFilter.doFilter(servletRequest, servletResponse, filterChain);
-
- verifyAll();
- }
-
- @Test
- public void testDoFilter_EmptyValuesNoSSL() throws Exception {
- final File httpPassFile = temporaryFolder.newFile();
-
- Injector injector = Guice.createInjector(new AbstractModule() {
-
- @Override
- protected void configure() {
- Properties properties = new Properties();
- properties.setProperty(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME_KEY, httpPassFile.getParent());
- properties.setProperty(Configuration.CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY, httpPassFile.getName());
- properties.setProperty(Configuration.HTTP_STRICT_TRANSPORT_HEADER_VALUE_KEY, "");
- properties.setProperty(Configuration.HTTP_X_FRAME_OPTIONS_HEADER_VALUE_KEY, "");
- properties.setProperty(Configuration.HTTP_X_XSS_PROTECTION_HEADER_VALUE_KEY, "");
-
- bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
- bind(Configuration.class).toInstance(new Configuration(properties));
- }
- });
-
- FilterConfig filterConfig = createNiceMock(FilterConfig.class);
-
- HttpServletRequest servletRequest = createStrictMock(HttpServletRequest.class);
-
- HttpServletResponse servletResponse = createStrictMock(HttpServletResponse.class);
-
- FilterChain filterChain = createStrictMock(FilterChain.class);
- filterChain.doFilter(servletRequest, servletResponse);
- expectLastCall().once();
-
- replayAll();
-
- SecurityHeaderFilter securityFilter = injector.getInstance(SecurityHeaderFilter.class);
- Assert.assertNotNull(securityFilter);
-
- securityFilter.init(filterConfig);
- securityFilter.doFilter(servletRequest, servletResponse, filterChain);
-
- verifyAll();
- }
-
- @Test
- public void testDoFilter_EmptyValuesSSL() throws Exception {
- final File httpPassFile = temporaryFolder.newFile();
-
- Injector injector = Guice.createInjector(new AbstractModule() {
-
- @Override
- protected void configure() {
- Properties properties = new Properties();
- properties.setProperty(Configuration.API_USE_SSL, "true");
- properties.setProperty(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME_KEY, httpPassFile.getParent());
- properties.setProperty(Configuration.CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY, httpPassFile.getName());
- properties.setProperty(Configuration.HTTP_STRICT_TRANSPORT_HEADER_VALUE_KEY, "");
- properties.setProperty(Configuration.HTTP_X_FRAME_OPTIONS_HEADER_VALUE_KEY, "");
- properties.setProperty(Configuration.HTTP_X_XSS_PROTECTION_HEADER_VALUE_KEY, "");
-
- bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
- bind(Configuration.class).toInstance(new Configuration(properties));
- }
- });
-
- FilterConfig filterConfig = createNiceMock(FilterConfig.class);
-
- HttpServletRequest servletRequest = createStrictMock(HttpServletRequest.class);
-
- HttpServletResponse servletResponse = createStrictMock(HttpServletResponse.class);
-
- FilterChain filterChain = createStrictMock(FilterChain.class);
- filterChain.doFilter(servletRequest, servletResponse);
- expectLastCall().once();
-
- replayAll();
-
- SecurityHeaderFilter securityFilter = injector.getInstance(SecurityHeaderFilter.class);
- Assert.assertNotNull(securityFilter);
-
- securityFilter.init(filterConfig);
- securityFilter.doFilter(servletRequest, servletResponse, filterChain);
-
- verifyAll();
- }
-}
\ No newline at end of file