QPID-8494: [Broker-J] Validate existance of Kerberos authentication provider only on creation
(cherry picked from commit f762d43017d2ccc3dab64c8a7027a03c90fdf366)
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java b/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java
index 69a9776..b1f13f5 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java
@@ -115,13 +115,20 @@
{
super.validateOnCreate();
validate(this);
+
+ if (_container.getChildren(AuthenticationProvider.class)
+ .stream()
+ .anyMatch(p -> p instanceof KerberosAuthenticationManager && p != this))
+ {
+ throw new IllegalConfigurationException("Another Kerberos authentication provider already exists."
+ + " Only one Kerberos authentication provider can be created.");
+ }
}
@Override
protected void validateChange(final ConfiguredObject<?> proxyForValidation, final Set<String> changedAttributes)
{
super.validateChange(proxyForValidation, changedAttributes);
- validate(proxyForValidation);
}
private void validate(final ConfiguredObject<?> authenticationProvider)
@@ -132,14 +139,5 @@
throw new IllegalConfigurationException(String.format(
"A path to non-existing file is specified in JVM system property '%s'", JAAS_CONFIG_PROPERTY));
}
-
- if (_container.getChildren(AuthenticationProvider.class)
- .stream()
- .anyMatch(p -> p instanceof KerberosAuthenticationManager
- && p != authenticationProvider))
- {
- throw new IllegalConfigurationException("Another Kerberos authentication provider already exists."
- + " Only one Kerberos authentication provider can be created.");
- }
}
}
diff --git a/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerTest.java b/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerTest.java
index 9211710..a2a2aaa 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerTest.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerTest.java
@@ -30,11 +30,13 @@
import static org.apache.qpid.server.test.KerberosUtilities.SERVICE_PRINCIPAL_NAME;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.File;
+import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Base64;
@@ -48,6 +50,7 @@
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslClient;
+import org.apache.qpid.server.security.TokenCarryingPrincipal;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
@@ -68,7 +71,8 @@
public class KerberosAuthenticationManagerTest extends UnitTestBase
{
-
+ private static final String ANOTHER_SERVICE = "foo/" + HOST_NAME;
+ private static final String ANOTHER_SERVICE_FULL_NAME = ANOTHER_SERVICE + "@" + REALM;
private static final KerberosUtilities UTILS = new KerberosUtilities();
@ClassRule
@@ -81,30 +85,27 @@
public static final SystemPropertySetter SYSTEM_PROPERTY_SETTER = new SystemPropertySetter();
private static File _clientKeyTabFile;
+ private static String _config;
private KerberosAuthenticationManager _kerberosAuthenticationProvider;
private Broker<?> _broker;
+ private SpnegoAuthenticator _spnegoAuthenticator;
@BeforeClass
public static void createKeyTabs() throws Exception
{
- UTILS.prepareConfiguration(HOST_NAME, SYSTEM_PROPERTY_SETTER);
+ KDC.createPrincipal("another.keytab", ANOTHER_SERVICE_FULL_NAME);
+ _config = UTILS.prepareConfiguration(HOST_NAME, SYSTEM_PROPERTY_SETTER);
_clientKeyTabFile = UTILS.prepareKeyTabs(KDC);
}
@Before
public void setUp() throws Exception
{
- Map<String, String> context = Collections.singletonMap(KerberosAuthenticationManager.GSSAPI_SPNEGO_CONFIG,
- ACCEPT_SCOPE);
- final Map<String, Object> attributes = new HashMap<>();
- attributes.put(AuthenticationProvider.NAME, getTestName());
- attributes.put(AuthenticationProvider.CONTEXT, context);
+ SYSTEM_PROPERTY_SETTER.setSystemProperty(LOGIN_CONFIG, _config);
_broker = BrokerTestHelper.createBrokerMock();
- _kerberosAuthenticationProvider = new KerberosAuthenticationManager(attributes, _broker);
- _kerberosAuthenticationProvider.create();
- when(_broker.getChildren(AuthenticationProvider.class))
- .thenReturn(Collections.singleton(_kerberosAuthenticationProvider));
+ _kerberosAuthenticationProvider = createKerberosAuthenticationProvider(ACCEPT_SCOPE);
+ _spnegoAuthenticator = new SpnegoAuthenticator(_kerberosAuthenticationProvider);
}
@Test
@@ -181,6 +182,105 @@
assertEquals(AuthenticationResult.AuthenticationStatus.SUCCESS, result.getStatus());
}
+ @Test
+ public void testAuthenticate() throws Exception
+ {
+ final String token = Base64.getEncoder().encodeToString(buildToken(SERVICE_PRINCIPAL_NAME));
+ final String authenticationHeader = SpnegoAuthenticator.NEGOTIATE_PREFIX + token;
+
+ final AuthenticationResult result = _spnegoAuthenticator.authenticate(authenticationHeader);
+
+ assertNotNull(result);
+ assertEquals(AuthenticationResult.AuthenticationStatus.SUCCESS, result.getStatus());
+ final Principal principal = result.getMainPrincipal();
+ assertTrue(principal instanceof TokenCarryingPrincipal);
+ assertEquals(KerberosUtilities.CLIENT_PRINCIPAL_FULL_NAME, principal.getName());
+
+ final Map<String, String> tokens = ((TokenCarryingPrincipal)principal).getTokens();
+ assertNotNull(tokens);
+ assertTrue(tokens.containsKey(SpnegoAuthenticator.RESPONSE_AUTH_HEADER_NAME));
+ }
+
+ @Test
+ public void testAuthenticateNoAuthenticationHeader()
+ {
+ final AuthenticationResult result = _spnegoAuthenticator.authenticate((String) null);
+ assertNotNull(result);
+ assertEquals(AuthenticationResult.AuthenticationStatus.ERROR, result.getStatus());
+ }
+
+ @Test
+ public void testAuthenticateNoNegotiatePrefix() throws Exception
+ {
+ final String token = Base64.getEncoder().encodeToString(buildToken(SERVICE_PRINCIPAL_NAME));
+ final AuthenticationResult result = _spnegoAuthenticator.authenticate(token);
+ assertNotNull(result);
+ assertEquals(AuthenticationResult.AuthenticationStatus.ERROR, result.getStatus());
+ }
+
+ @Test
+ public void testAuthenticateEmptyToken()
+ {
+ final AuthenticationResult result =
+ _spnegoAuthenticator.authenticate(SpnegoAuthenticator.NEGOTIATE_PREFIX + "");
+ assertNotNull(result);
+ assertEquals(AuthenticationResult.AuthenticationStatus.ERROR, result.getStatus());
+ }
+
+ @Test
+ public void testAuthenticateInvalidToken()
+ {
+ final AuthenticationResult result =
+ _spnegoAuthenticator.authenticate(SpnegoAuthenticator.NEGOTIATE_PREFIX + "Zm9v");
+ assertNotNull(result);
+ assertEquals(AuthenticationResult.AuthenticationStatus.ERROR, result.getStatus());
+ }
+
+ @Test
+ public void testAuthenticateWrongConfigName() throws Exception
+ {
+ _kerberosAuthenticationProvider.delete();
+
+ _kerberosAuthenticationProvider = createKerberosAuthenticationProvider("foo");
+ _spnegoAuthenticator = new SpnegoAuthenticator(_kerberosAuthenticationProvider);
+
+ final String token = Base64.getEncoder().encodeToString(buildToken(SERVICE_PRINCIPAL_NAME));
+ final String authenticationHeader = SpnegoAuthenticator.NEGOTIATE_PREFIX + token;
+
+ final AuthenticationResult result = _spnegoAuthenticator.authenticate(authenticationHeader);
+ assertNotNull(result);
+ assertEquals(AuthenticationResult.AuthenticationStatus.ERROR, result.getStatus());
+ }
+
+ @Test
+ public void testAuthenticateWrongServer() throws Exception
+ {
+ final String token = Base64.getEncoder().encodeToString(buildToken(ANOTHER_SERVICE));
+ final String authenticationHeader = SpnegoAuthenticator.NEGOTIATE_PREFIX + token;
+
+ final AuthenticationResult result = _spnegoAuthenticator.authenticate(authenticationHeader);
+ assertNotNull(result);
+ assertEquals(AuthenticationResult.AuthenticationStatus.ERROR, result.getStatus());
+ }
+
+ private KerberosAuthenticationManager createKerberosAuthenticationProvider(String acceptScope)
+ {
+ when(_broker.getChildren(AuthenticationProvider.class)).thenReturn(Collections.emptyList());
+ final Map<String, String> context = Collections.singletonMap(KerberosAuthenticationManager.GSSAPI_SPNEGO_CONFIG, acceptScope);
+ final Map<String, Object> attributes = new HashMap<>();
+ attributes.put(AuthenticationProvider.NAME, getTestName());
+ attributes.put(AuthenticationProvider.CONTEXT, context);
+ KerberosAuthenticationManager kerberosAuthenticationProvider = new KerberosAuthenticationManager(attributes, _broker);
+ kerberosAuthenticationProvider.create();
+ when(_broker.getChildren(AuthenticationProvider.class)).thenReturn(Collections.singleton(kerberosAuthenticationProvider));
+ return kerberosAuthenticationProvider;
+ }
+
+ private byte[] buildToken(final String anotherService) throws Exception
+ {
+ return UTILS.buildToken(KerberosUtilities.CLIENT_PRINCIPAL_NAME, _clientKeyTabFile, anotherService);
+ }
+
private AuthenticationResult authenticate(final SaslNegotiator negotiator) throws Exception
{
final LoginContext lc = UTILS.createKerberosKeyTabLoginContext(getTestName(),
diff --git a/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SpnegoAuthenticatorTest.java b/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SpnegoAuthenticatorTest.java
deleted file mode 100644
index bbd65a4..0000000
--- a/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SpnegoAuthenticatorTest.java
+++ /dev/null
@@ -1,164 +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.qpid.server.security.auth.manager;
-
-import static org.apache.qpid.server.test.KerberosUtilities.ACCEPT_SCOPE;
-import static org.apache.qpid.server.test.KerberosUtilities.HOST_NAME;
-import static org.apache.qpid.server.test.KerberosUtilities.REALM;
-import static org.apache.qpid.server.test.KerberosUtilities.SERVICE_PRINCIPAL_NAME;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.File;
-import java.security.Principal;
-import java.util.Base64;
-import java.util.Map;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-import org.apache.qpid.server.security.TokenCarryingPrincipal;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.test.EmbeddedKdcResource;
-import org.apache.qpid.server.test.KerberosUtilities;
-import org.apache.qpid.test.utils.SystemPropertySetter;
-import org.apache.qpid.test.utils.UnitTestBase;
-
-public class SpnegoAuthenticatorTest extends UnitTestBase
-{
- private static final String ANOTHER_SERVICE = "foo/" + HOST_NAME;
- private static final String ANOTHER_SERVICE_FULL_NAME = ANOTHER_SERVICE + "@" + REALM;
- private static final KerberosUtilities UTILS = new KerberosUtilities();
-
- @ClassRule
- public static final EmbeddedKdcResource KDC = new EmbeddedKdcResource(HOST_NAME, 0, "QpidTestKerberosServer", REALM);
-
- @ClassRule
- public static final SystemPropertySetter SYSTEM_PROPERTY_SETTER = new SystemPropertySetter();
- private static File _clientKeyTab;
-
- private SpnegoAuthenticator _spnegoAuthenticator;
- private KerberosAuthenticationManager _kerberosAuthenticationManager;
-
- @BeforeClass
- public static void createKeyTabs() throws Exception
- {
- KDC.createPrincipal("another.keytab", ANOTHER_SERVICE_FULL_NAME);
- UTILS.prepareConfiguration(HOST_NAME, SYSTEM_PROPERTY_SETTER);
- _clientKeyTab = UTILS.prepareKeyTabs(KDC);
- }
-
- @Before
- public void setUp()
- {
- _kerberosAuthenticationManager = mock(KerberosAuthenticationManager.class);
- when(_kerberosAuthenticationManager.getSpnegoLoginConfigScope()).thenReturn(ACCEPT_SCOPE);
- when(_kerberosAuthenticationManager.isStripRealmFromPrincipalName()).thenReturn(true);
-
- _spnegoAuthenticator = new SpnegoAuthenticator(_kerberosAuthenticationManager);
- }
-
- @Test
- public void testAuthenticate() throws Exception
- {
- final String token = Base64.getEncoder().encodeToString(buildToken(SERVICE_PRINCIPAL_NAME));
- final String authenticationHeader = SpnegoAuthenticator.NEGOTIATE_PREFIX + token;
-
- final AuthenticationResult result = _spnegoAuthenticator.authenticate(authenticationHeader);
-
- assertNotNull(result);
- assertEquals(AuthenticationResult.AuthenticationStatus.SUCCESS, result.getStatus());
- final Principal principal = result.getMainPrincipal();
- assertTrue(principal instanceof TokenCarryingPrincipal);
- assertEquals(KerberosUtilities.CLIENT_PRINCIPAL_NAME, principal.getName());
-
- final Map<String, String> tokens = ((TokenCarryingPrincipal)principal).getTokens();
- assertNotNull(tokens);
- assertTrue(tokens.containsKey(SpnegoAuthenticator.RESPONSE_AUTH_HEADER_NAME));
- }
-
- @Test
- public void testAuthenticateNoAuthenticationHeader()
- {
- final AuthenticationResult result = _spnegoAuthenticator.authenticate((String) null);
- assertNotNull(result);
- assertEquals(AuthenticationResult.AuthenticationStatus.ERROR, result.getStatus());
- }
-
- @Test
- public void testAuthenticateNoNegotiatePrefix() throws Exception
- {
- final String token = Base64.getEncoder().encodeToString(buildToken(SERVICE_PRINCIPAL_NAME));
- final AuthenticationResult result = _spnegoAuthenticator.authenticate(token);
- assertNotNull(result);
- assertEquals(AuthenticationResult.AuthenticationStatus.ERROR, result.getStatus());
- }
-
- @Test
- public void testAuthenticateEmptyToken()
- {
- final AuthenticationResult result =
- _spnegoAuthenticator.authenticate(SpnegoAuthenticator.NEGOTIATE_PREFIX + "");
- assertNotNull(result);
- assertEquals(AuthenticationResult.AuthenticationStatus.ERROR, result.getStatus());
- }
-
- @Test
- public void testAuthenticateInvalidToken()
- {
- final AuthenticationResult result =
- _spnegoAuthenticator.authenticate(SpnegoAuthenticator.NEGOTIATE_PREFIX + "Zm9v");
- assertNotNull(result);
- assertEquals(AuthenticationResult.AuthenticationStatus.ERROR, result.getStatus());
- }
-
- @Test
- public void testAuthenticateWrongConfigName() throws Exception
- {
- when(_kerberosAuthenticationManager.getSpnegoLoginConfigScope()).thenReturn("foo");
- final String token = Base64.getEncoder().encodeToString(buildToken(SERVICE_PRINCIPAL_NAME));
- final String authenticationHeader = SpnegoAuthenticator.NEGOTIATE_PREFIX + token;
-
- final AuthenticationResult result = _spnegoAuthenticator.authenticate(authenticationHeader);
- assertNotNull(result);
- assertEquals(AuthenticationResult.AuthenticationStatus.ERROR, result.getStatus());
- }
-
- @Test
- public void testAuthenticateWrongServer() throws Exception
- {
- final String token = Base64.getEncoder().encodeToString(buildToken(ANOTHER_SERVICE));
- final String authenticationHeader = SpnegoAuthenticator.NEGOTIATE_PREFIX + token;
-
- final AuthenticationResult result = _spnegoAuthenticator.authenticate(authenticationHeader);
- assertNotNull(result);
- assertEquals(AuthenticationResult.AuthenticationStatus.ERROR, result.getStatus());
- }
-
- private byte[] buildToken(final String anotherService) throws Exception
- {
- return UTILS.buildToken(KerberosUtilities.CLIENT_PRINCIPAL_NAME, _clientKeyTab, anotherService);
- }
-}
diff --git a/broker-core/src/test/java/org/apache/qpid/server/test/KerberosUtilities.java b/broker-core/src/test/java/org/apache/qpid/server/test/KerberosUtilities.java
index 13c3acc..f1c62bf 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/test/KerberosUtilities.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/test/KerberosUtilities.java
@@ -95,13 +95,14 @@
return clientKeyTabFile;
}
- public void prepareConfiguration(final String hostName, final SystemPropertySetter systemPropertySetter)
+ public String prepareConfiguration(final String hostName, final SystemPropertySetter systemPropertySetter)
throws IOException
{
final Path loginConfig = transformLoginConfig(hostName);
- systemPropertySetter.setSystemProperty(LOGIN_CONFIG,
- URLDecoder.decode(loginConfig.toFile().getAbsolutePath(), UTF_8.name()));
+ final String configLocation = URLDecoder.decode(loginConfig.toFile().getAbsolutePath(), UTF_8.name());
+ systemPropertySetter.setSystemProperty(LOGIN_CONFIG, configLocation);
systemPropertySetter.setSystemProperty(USE_SUBJECT_CREDS_ONLY, "false");
+ return configLocation;
}
public byte[] buildToken(String clientPrincipalName, File clientKeyTabFile, String targetServerPrincipalName)