Repository: ambari Updated Branches: refs/heads/branch-2.5 3f28809f2 -> d346558c1
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/d346558c Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d346558c Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d346558c Branch: refs/heads/branch-2.5 Commit: d346558c129684ca06e9dc84d666321236c51840 Parents: 3f28809 Author: Robert Levas <[email protected]> Authored: Fri Jan 6 20:46:28 2017 -0500 Committer: Robert Levas <[email protected]> Committed: Fri Jan 6 20:46:28 2017 -0500 ---------------------------------------------------------------------- .../server/security/AmbariEntryPoint.java | 31 +++++-- .../webapp/WEB-INF/spring-security.xml | 1 + .../server/security/AmbariEntryPointTest.java | 88 ++++++++++++++++++++ 3 files changed, 114 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/d346558c/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 e37976f..1545f71 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 @@ -17,26 +17,45 @@ */ package org.apache.ambari.server.security; +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; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; + import java.io.IOException; 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/d346558c/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/d346558c/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..d37adc6 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariEntryPointTest.java @@ -0,0 +1,88 @@ +/* + * 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 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; + +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; + +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(); + + } + +} \ No newline at end of file
