ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rle...@apache.org
Subject ambari git commit: AMBARI-13278. Add security-related HTTP headers to keep Ambari up to date with best-practices (rlevas)
Date Thu, 01 Oct 2015 18:52:07 GMT
Repository: ambari
Updated Branches:
  refs/heads/branch-2.0.maint d61fdf4dc -> 071c2d527


AMBARI-13278. Add security-related HTTP headers to keep Ambari up to date with best-practices
(rlevas)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/071c2d52
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/071c2d52
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/071c2d52

Branch: refs/heads/branch-2.0.maint
Commit: 071c2d527e7bc1538a3957d576a52736eac04327
Parents: d61fdf4
Author: Robert Levas <rlevas@hortonworks.com>
Authored: Thu Oct 1 14:51:56 2015 -0400
Committer: Robert Levas <rlevas@hortonworks.com>
Committed: Thu Oct 1 14:51:56 2015 -0400

----------------------------------------------------------------------
 ambari-server/conf/unix/ambari.properties       |   5 +
 ambari-server/conf/windows/ambari.properties    |   5 +
 .../server/configuration/Configuration.java     |  58 ++++
 .../ambari/server/controller/AmbariServer.java  |   3 +
 .../server/security/SecurityHeaderFilter.java   | 121 +++++++
 .../security/SecurityHeaderFilterTest.java      | 318 +++++++++++++++++++
 6 files changed, 510 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/071c2d52/ambari-server/conf/unix/ambari.properties
----------------------------------------------------------------------
diff --git a/ambari-server/conf/unix/ambari.properties b/ambari-server/conf/unix/ambari.properties
index b11fa5f..1fbef08 100644
--- a/ambari-server/conf/unix/ambari.properties
+++ b/ambari-server/conf/unix/ambari.properties
@@ -83,3 +83,8 @@ ulimit.open.files=10000
 
 # Server HTTP settings
 server.http.session.inactive_timeout=1800
+
+# HTTP Header settings
+http.strict-transport-security=max-age=31536000
+http.x-xss-protection=1; mode=block
+http.x-frame-options=DENY

http://git-wip-us.apache.org/repos/asf/ambari/blob/071c2d52/ambari-server/conf/windows/ambari.properties
----------------------------------------------------------------------
diff --git a/ambari-server/conf/windows/ambari.properties b/ambari-server/conf/windows/ambari.properties
index d0fb6dd..1f3182d 100644
--- a/ambari-server/conf/windows/ambari.properties
+++ b/ambari-server/conf/windows/ambari.properties
@@ -84,3 +84,8 @@ ulimit.open.files=10000
 #server.jdbc.schema=ambari
 ##server.jdbc.user.passwd=etc\\ambari-server\\conf\\password.dat
 ##server.jdbc.user.name=ambari
+
+# HTTP Header settings
+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://git-wip-us.apache.org/repos/asf/ambari/blob/071c2d52/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 8060c80..b089a92 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
@@ -336,6 +336,16 @@ public class Configuration {
    */
   private static final String ALERT_TEMPLATE_FILE = "alerts.template.file";
 
+  /**
+   *   For HTTP Response header configuration
+   */
+  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";
+  public static final String HTTP_X_FRAME_OPTIONS_HEADER_VALUE_KEY = "http.x-frame-options";
+  public static final String HTTP_X_FRAME_OPTIONS_HEADER_VALUE_DEFAULT = "DENY";
+  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";
+
   private static final Logger LOG = LoggerFactory.getLogger(
       Configuration.class);
 
@@ -793,6 +803,54 @@ public class Configuration {
   }
 
   /**
+   * Get the value that should be set for the <code>Strict-Transport-Security</code>
HTTP response header.
+   * <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 getStrictTransportSecurityHTTPResponseHeader() {
+    return properties.getProperty(HTTP_STRICT_TRANSPORT_HEADER_VALUE_KEY, HTTP_STRICT_TRANSPORT_HEADER_VALUE_DEFAULT);
+  }
+
+  /**
+   * Get the value that should be set for the <code>X-Frame-Options</code> HTTP
response header.
+   * <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 getXFrameOptionsHTTPResponseHeader() {
+    return properties.getProperty(HTTP_X_FRAME_OPTIONS_HEADER_VALUE_KEY, HTTP_X_FRAME_OPTIONS_HEADER_VALUE_DEFAULT);
+  }
+
+  /**
+   * Get the value that should be set for the <code>X-XSS-Protection</code> HTTP
response header.
+   * <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 getXXSSProtectionHTTPResponseHeader() {
+    return properties.getProperty(HTTP_X_XSS_PROTECTION_HEADER_VALUE_KEY, 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/071c2d52/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 a0231af..d9581ab 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
@@ -78,6 +78,7 @@ 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.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;
@@ -281,6 +282,8 @@ public class AmbariServer {
       rootServlet = agentroot.addServlet(DefaultServlet.class, "/");
       rootServlet.setInitOrder(1);
 
+      // Conditionally adds security-related headers to all HTTP responses.
+      root.addFilter(new FilterHolder(injector.getInstance(SecurityHeaderFilter.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/071c2d52/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
new file mode 100644
index 0000000..a7479af
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityHeaderFilter.java
@@ -0,0 +1,121 @@
+/*
+ * 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/071c2d52/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
new file mode 100644
index 0000000..5e8d2af
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/SecurityHeaderFilterTest.java
@@ -0,0 +1,318 @@
+/*
+ * 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


Mime
View raw message