Repository: ambari Updated Branches: refs/heads/trunk 21d4aff0b -> fc586a87a
AMBARI-19389. Authentication negotiation HTTP response should be sent when Kerberos authentication is enabled (rlevas) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/fc586a87 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/fc586a87 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/fc586a87 Branch: refs/heads/trunk Commit: fc586a87aa466c2fda12ef36b0ddee1e63b9e174 Parents: 21d4aff Author: Robert Levas <[email protected]> Authored: Fri Jan 6 16:25:19 2017 -0500 Committer: Robert Levas <[email protected]> Committed: Fri Jan 6 16:25:23 2017 -0500 ---------------------------------------------------------------------- .../server/security/AmbariEntryPoint.java | 30 +++++++-- .../webapp/WEB-INF/spring-security.xml | 1 + .../server/security/AmbariEntryPointTest.java | 70 ++++++++++++++++++++ 3 files changed, 95 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/fc586a87/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariEntryPoint.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariEntryPoint.java b/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariEntryPoint.java index 7e0ff79..8c7dd72 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariEntryPoint.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariEntryPoint.java @@ -23,21 +23,39 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.ambari.server.configuration.Configuration; +import org.apache.ambari.server.security.authentication.kerberos.AmbariKerberosAuthenticationProperties; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; public class AmbariEntryPoint implements AuthenticationEntryPoint { + + /** + * A Boolean value declaring whether Kerberos authentication has been enabled (<code>true</code>) + * or not (<code>false</code>). + * <p> + * This value determines the behavior this entry point when authentication fails. + */ + private final boolean kerberosAuthenticationEnabled; + + public AmbariEntryPoint(Configuration configuration) { + AmbariKerberosAuthenticationProperties kerberosAuthenticationProperties = (configuration == null) + ? null + : configuration.getKerberosAuthenticationProperties(); + + kerberosAuthenticationEnabled = (kerberosAuthenticationProperties != null) && kerberosAuthenticationProperties.isKerberosAuthenticationEnabled(); + } + @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { /* ***************************************************************************************** - * To maintain backward compatibility and respond with the appropriate response when - * authentication is needed, by default return an HTTP 403 status. + * If Kerberos authentication is enabled (authentication.kerberos.enabled = true), respond such + * that the client is challenged to Negotiate and reissue the request with a Kerberos token. + * This response is an HTTP 401 status with the "WWW-Authenticate: Negotiate" header. * - * However if requested by the user, respond such that the client is challenged to Negotiate - * and reissue the request with a Kerberos token. This response is an HTTP 401 status with the - * WWW-Authenticate: Negotiate" header. + * If Kerberos authentication is not enabled, return an HTTP 403 status. * ****************************************************************************************** */ - if ("true".equalsIgnoreCase(request.getHeader("X-Negotiate-Authentication"))) { + if (kerberosAuthenticationEnabled) { response.setHeader("WWW-Authenticate", "Negotiate"); response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication requested"); } else { http://git-wip-us.apache.org/repos/asf/ambari/blob/fc586a87/ambari-server/src/main/resources/webapp/WEB-INF/spring-security.xml ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/webapp/WEB-INF/spring-security.xml b/ambari-server/src/main/resources/webapp/WEB-INF/spring-security.xml index 9eca920..bdbf0de 100644 --- a/ambari-server/src/main/resources/webapp/WEB-INF/spring-security.xml +++ b/ambari-server/src/main/resources/webapp/WEB-INF/spring-security.xml @@ -39,6 +39,7 @@ </authentication-manager> <beans:bean id="ambariEntryPoint" class="org.apache.ambari.server.security.AmbariEntryPoint"> + <beans:constructor-arg ref="ambariConfiguration"/> </beans:bean> <beans:bean id="ambariDelegatingAuthenticationFilter" class="org.apache.ambari.server.security.authentication.AmbariDelegatingAuthenticationFilter"> http://git-wip-us.apache.org/repos/asf/ambari/blob/fc586a87/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariEntryPointTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariEntryPointTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariEntryPointTest.java new file mode 100644 index 0000000..3881443 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariEntryPointTest.java @@ -0,0 +1,70 @@ +package org.apache.ambari.server.security; + +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; + +import java.io.IOException; +import java.util.Properties; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.ambari.server.configuration.Configuration; +import org.easymock.EasyMockSupport; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.springframework.security.core.AuthenticationException; + +public class AmbariEntryPointTest extends EasyMockSupport { + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Test + public void testCommenceDefault() throws Exception { + testCommence(null); + } + + @Test + public void testCommenceKerberosAuthenticationEnabled() throws Exception { + testCommence(Boolean.TRUE); + } + + @Test + public void testCommenceKerberosAuthenticationNotEnabled() throws Exception { + testCommence(Boolean.FALSE); + } + + private void testCommence(Boolean kerberosAuthenticationEnabled) throws IOException, ServletException { + HttpServletRequest request = createStrictMock(HttpServletRequest.class); + HttpServletResponse response = createStrictMock(HttpServletResponse.class); + AuthenticationException exception = createStrictMock(AuthenticationException.class); + + if (Boolean.TRUE == kerberosAuthenticationEnabled) { + response.setHeader("WWW-Authenticate", "Negotiate"); + expectLastCall().once(); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication requested"); + expectLastCall().once(); + } else { + expect(exception.getMessage()).andReturn("message").once(); + response.sendError(HttpServletResponse.SC_FORBIDDEN, "message"); + expectLastCall().once(); + } + + replayAll(); + + + Properties properties = new Properties(); + if (kerberosAuthenticationEnabled != null) { + properties.setProperty(Configuration.KERBEROS_AUTH_ENABLED.getKey(), kerberosAuthenticationEnabled.toString()); + properties.setProperty(Configuration.KERBEROS_AUTH_SPNEGO_KEYTAB_FILE.getKey(), temporaryFolder.newFile().getAbsolutePath()); + } + AmbariEntryPoint entryPoint = new AmbariEntryPoint(new Configuration(properties)); + entryPoint.commence(request, response, exception); + + verifyAll(); + + } + +}
