diff options
Diffstat (limited to 'java/broker/src/main/java/org/apache/qpid/server/security/auth/manager')
15 files changed, 443 insertions, 932 deletions
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java new file mode 100644 index 0000000000..ff21d63c87 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java @@ -0,0 +1,71 @@ +/* + * 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 java.io.IOException; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; +import org.apache.qpid.server.security.auth.database.PrincipalDatabase; + +/** + * Factory for {@link PrincipalDatabaseAuthenticationManager} objects configured + * with either the Plain or Base64MD5 digest {@link PrincipalDatabase} + * implementation. + */ +public abstract class AbstractPrincipalDatabaseAuthManagerFactory implements AuthenticationManagerFactory +{ + public static final String ATTRIBUTE_PATH = "path"; + + private static final Logger LOGGER = Logger.getLogger(AbstractPrincipalDatabaseAuthManagerFactory.class); + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes == null || !getType().equals(attributes.get(ATTRIBUTE_TYPE))) + { + return null; + } + + String passwordFile = (String) attributes.get(ATTRIBUTE_PATH); + if (passwordFile == null) + { + LOGGER.warn("Password file path must not be null"); + return null; + } + + PrincipalDatabase principalDatabase = createPrincipalDatabase(); + try + { + principalDatabase.setPasswordFile(passwordFile); + } + catch (IOException e) + { + throw new RuntimeException(e.getMessage(), e); + } + + return new PrincipalDatabaseAuthenticationManager(principalDatabase); + } + + abstract String getType(); + + abstract PrincipalDatabase createPrincipalDatabase(); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java index 5676c43754..dd4c2e717a 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java @@ -21,31 +21,25 @@ package org.apache.qpid.server.security.auth.manager; import java.security.Principal; -import java.util.Arrays; -import java.util.List; + import javax.security.auth.Subject; -import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; + import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.sasl.anonymous.AnonymousInitialiser; import org.apache.qpid.server.security.auth.sasl.anonymous.AnonymousSaslServer; public class AnonymousAuthenticationManager implements AuthenticationManager { - private static final Logger _logger = Logger.getLogger(AnonymousAuthenticationManager.class); - private static final AnonymousInitialiser SASL_INITIALISER = new AnonymousInitialiser(); private static final String ANONYMOUS = SASL_INITIALISER.getMechanismName(); - private static final Principal ANONYMOUS_PRINCIPAL = new UsernamePrincipal("ANONYMOUS"); + public static final String ANONYMOUS_USERNAME = "ANONYMOUS"; + + public static final Principal ANONYMOUS_PRINCIPAL = new UsernamePrincipal(ANONYMOUS_USERNAME); public static final Subject ANONYMOUS_SUBJECT = new Subject(); static @@ -53,76 +47,11 @@ public class AnonymousAuthenticationManager implements AuthenticationManager ANONYMOUS_SUBJECT.getPrincipals().add(ANONYMOUS_PRINCIPAL); } - private static final AuthenticationResult ANONYMOUS_AUTHENTICATION = new AuthenticationResult(ANONYMOUS_SUBJECT); - - - private static CallbackHandler _callbackHandler = SASL_INITIALISER.getCallbackHandler(); + private static final AuthenticationResult ANONYMOUS_AUTHENTICATION = new AuthenticationResult(ANONYMOUS_PRINCIPAL); static final AnonymousAuthenticationManager INSTANCE = new AnonymousAuthenticationManager(); - public static class AnonymousAuthenticationManagerConfiguration extends ConfigurationPlugin - { - - public static final ConfigurationPluginFactory FACTORY = - new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.anonymous-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new AnonymousAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[0]; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - } - - - public static final AuthenticationManagerPluginFactory<AnonymousAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<AnonymousAuthenticationManager>() - { - public AnonymousAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - AnonymousAuthenticationManagerConfiguration configuration = - config == null - ? null - : (AnonymousAuthenticationManagerConfiguration) config.getConfiguration(AnonymousAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for AnonymousAuthenticationManager"); - return null; - } - return INSTANCE; - } - - public Class<AnonymousAuthenticationManager> getPluginClass() - { - return AnonymousAuthenticationManager.class; - } - - public String getPluginName() - { - return AnonymousAuthenticationManager.class.getName(); - } - }; - - - private AnonymousAuthenticationManager() + AnonymousAuthenticationManager() { } @@ -184,9 +113,4 @@ public class AnonymousAuthenticationManager implements AuthenticationManager public void close() { } - - @Override - public void configure(ConfigurationPlugin config) throws ConfigurationException - { - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java new file mode 100644 index 0000000000..1b1995500c --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java @@ -0,0 +1,40 @@ +/* + * 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 java.util.Map; + +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; + +public class AnonymousAuthenticationManagerFactory implements AuthenticationManagerFactory +{ + public static final String PROVIDER_TYPE = AnonymousAuthenticationManager.class.getSimpleName(); + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE))) + { + return new AnonymousAuthenticationManager(); + } + return null; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java index ccddcb7669..c1a694f148 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java @@ -24,22 +24,22 @@ import java.security.Principal; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import org.apache.qpid.common.Closeable; -import org.apache.qpid.server.plugins.Plugin; import org.apache.qpid.server.security.auth.AuthenticationResult; /** * Implementations of the AuthenticationManager are responsible for determining * the authenticity of a user's credentials. - * - * If the authentication is successful, the manager is responsible for producing a populated - * {@link javax.security.auth.Subject} containing the user's identity and zero or more principals representing - * groups to which the user belongs. + * <p> + * If the authentication is successful, the manager is responsible for producing an + * {@link AuthenticationResult} containing the user's main {@link Principal} and zero or + * more other implementation-specific principals. + * </p> * <p> * The {@link #initialise()} method is responsible for registering SASL mechanisms required by * the manager. The {@link #close()} method must reverse this registration. - * + * </p> */ -public interface AuthenticationManager extends Closeable, Plugin +public interface AuthenticationManager extends Closeable { /** The name for the required SASL Server mechanisms */ public static final String PROVIDER_NAME= "AMQSASLProvider-Server"; @@ -88,5 +88,4 @@ public interface AuthenticationManager extends Closeable, Plugin * @return authentication result */ AuthenticationResult authenticate(String username, String password); - } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java deleted file mode 100644 index 89a4d8ae66..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java +++ /dev/null @@ -1,203 +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 java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.commons.configuration.ConfigurationException; -import org.apache.qpid.common.Closeable; -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.plugins.Plugin; -import org.apache.qpid.server.plugins.PluginManager; -import org.apache.qpid.server.security.SecurityManager.SecurityConfiguration; - -/** - * A concrete implementation of {@link IAuthenticationManagerRegistry} that registers all {@link AuthenticationManager} - * instances defined in the configuration, building an optional mapping between port number and AuthenticationManager. - * - * <p>The default AuthenticationManager is either the one nominated as default within the configuration with - * {@link ServerConfiguration#getDefaultAuthenticationManager()}, or if there is only one, it is implicitly - * the default.</p> - * - * <p>It is important to {@link #close()} the registry after use and this allows the AuthenticationManagers - * to reverse any security registrations they have performed.</p> - */ -public class AuthenticationManagerRegistry implements Closeable, IAuthenticationManagerRegistry -{ - private final Map<String,AuthenticationManager> _classToAuthManagerMap = new HashMap<String,AuthenticationManager>(); - private final AuthenticationManager _defaultAuthenticationManager; - private final Map<Integer,AuthenticationManager> _portToAuthenticationManagerMap; - private final List<RegistryChangeListener> _listeners = - Collections.synchronizedList(new ArrayList<RegistryChangeListener>()); - - public AuthenticationManagerRegistry(ServerConfiguration serverConfiguration, PluginManager _pluginManager) - throws ConfigurationException - { - final Collection<AuthenticationManagerPluginFactory<? extends Plugin>> factories = _pluginManager.getAuthenticationManagerPlugins().values(); - - if (factories.size() == 0) - { - throw new ConfigurationException("No authentication manager factory plugins found. Check the desired authentication" + - " manager plugin has been placed in the plugins directory."); - } - - final SecurityConfiguration securityConfiguration = serverConfiguration.getConfiguration(SecurityConfiguration.class.getName()); - - boolean willClose = true; - try - { - createAuthenticationManagersRejectingDuplicates(factories, securityConfiguration); - - if(_classToAuthManagerMap.isEmpty()) - { - throw new ConfigurationException("No authentication managers configured within the configuration file."); - } - - _defaultAuthenticationManager = getDefaultAuthenticationManager(serverConfiguration); - - _portToAuthenticationManagerMap = getPortToAuthenticationManagerMap(serverConfiguration); - willClose = false; - } - finally - { - // if anything went wrong whilst configuring the registry, try to close all the AuthentcationManagers instantiated so far. - // This is done to allow the AuthenticationManager to undo any security registrations that they have performed. - if (willClose) - { - close(); - } - } - } - - @Override - public AuthenticationManager getAuthenticationManager(SocketAddress address) - { - AuthenticationManager authManager = - address instanceof InetSocketAddress - ? _portToAuthenticationManagerMap.get(((InetSocketAddress)address).getPort()) - : null; - - return authManager == null ? _defaultAuthenticationManager : authManager; - } - - @Override - public void close() - { - for (AuthenticationManager authManager : _classToAuthManagerMap.values()) - { - authManager.close(); - } - } - - private void createAuthenticationManagersRejectingDuplicates( - final Collection<AuthenticationManagerPluginFactory<? extends Plugin>> factories, - final SecurityConfiguration securityConfiguration) - throws ConfigurationException - { - for(AuthenticationManagerPluginFactory<? extends Plugin> factory : factories) - { - final AuthenticationManager tmp = factory.newInstance(securityConfiguration); - if (tmp != null) - { - if(_classToAuthManagerMap.containsKey(tmp.getClass().getSimpleName())) - { - throw new ConfigurationException("Cannot configure more than one authentication manager of type " - + tmp.getClass().getSimpleName() + "." - + " Remove configuration for one of the authentication managers."); - } - _classToAuthManagerMap.put(tmp.getClass().getSimpleName(),tmp); - - for(RegistryChangeListener listener : _listeners) - { - listener.authenticationManagerRegistered(tmp); - } - } - } - } - - private AuthenticationManager getDefaultAuthenticationManager( - ServerConfiguration serverConfiguration) - throws ConfigurationException - { - final AuthenticationManager defaultAuthenticationManager; - if(_classToAuthManagerMap.size() == 1) - { - defaultAuthenticationManager = _classToAuthManagerMap.values().iterator().next(); - } - else if(serverConfiguration.getDefaultAuthenticationManager() != null) - { - defaultAuthenticationManager = _classToAuthManagerMap.get(serverConfiguration.getDefaultAuthenticationManager()); - if(defaultAuthenticationManager == null) - { - throw new ConfigurationException("No authentication managers configured of type " - + serverConfiguration.getDefaultAuthenticationManager() - + " which is specified as the default. Available managers are: " - + _classToAuthManagerMap.keySet()); - } - } - else - { - throw new ConfigurationException("If more than one authentication manager is configured a default MUST be specified."); - } - return defaultAuthenticationManager; - } - - private Map<Integer,AuthenticationManager> getPortToAuthenticationManagerMap( - ServerConfiguration serverConfiguration) - throws ConfigurationException - { - Map<Integer,AuthenticationManager> portToAuthenticationManagerMap = new HashMap<Integer, AuthenticationManager>(); - - for(Map.Entry<Integer,String> portMapping : serverConfiguration.getPortAuthenticationMappings().entrySet()) - { - - AuthenticationManager authenticationManager = _classToAuthManagerMap.get(portMapping.getValue()); - if(authenticationManager == null) - { - throw new ConfigurationException("Unknown authentication manager class " + portMapping.getValue() + - " configured for port " + portMapping.getKey()); - } - portToAuthenticationManagerMap.put(portMapping.getKey(), authenticationManager); - } - - return portToAuthenticationManagerMap; - } - - @Override - public Map<String, AuthenticationManager> getAvailableAuthenticationManagers() - { - return Collections.unmodifiableMap(new HashMap<String, AuthenticationManager>(_classToAuthManagerMap)); - } - - @Override - public void addRegistryChangeListener(RegistryChangeListener listener) - { - _listeners.add(listener); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java new file mode 100644 index 0000000000..c61567ef77 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java @@ -0,0 +1,42 @@ +/* + * + * 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 org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase; +import org.apache.qpid.server.security.auth.database.PrincipalDatabase; + +public class Base64MD5PasswordFileAuthenticationManagerFactory extends AbstractPrincipalDatabaseAuthManagerFactory +{ + public static final String PROVIDER_TYPE = "Base64MD5PasswordFileAuthenticationProvider"; + + @Override + String getType() + { + return PROVIDER_TYPE; + } + + @Override + PrincipalDatabase createPrincipalDatabase() + { + return new Base64MD5PasswordFilePrincipalDatabase(); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java index 2d6866b657..9ed8cf7fed 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java @@ -19,90 +19,19 @@ package org.apache.qpid.server.security.auth.manager; import java.security.Principal; -import java.util.Arrays; -import java.util.List; -import javax.security.auth.Subject; + import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; + import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.sasl.external.ExternalSaslServer; public class ExternalAuthenticationManager implements AuthenticationManager { - private static final Logger _logger = Logger.getLogger(ExternalAuthenticationManager.class); - private static final String EXTERNAL = "EXTERNAL"; - static final ExternalAuthenticationManager INSTANCE = new ExternalAuthenticationManager(); - - public static class ExternalAuthenticationManagerConfiguration extends ConfigurationPlugin - { - - public static final ConfigurationPluginFactory FACTORY = - new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.external-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new ExternalAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[0]; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - } - - - public static final AuthenticationManagerPluginFactory<ExternalAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<ExternalAuthenticationManager>() - { - public ExternalAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - ExternalAuthenticationManagerConfiguration configuration = - config == null - ? null - : (ExternalAuthenticationManagerConfiguration) config.getConfiguration(ExternalAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for ExternalAuthenticationManager"); - return null; - } - return INSTANCE; - } - - public Class<ExternalAuthenticationManager> getPluginClass() - { - return ExternalAuthenticationManager.class; - } - - public String getPluginName() - { - return ExternalAuthenticationManager.class.getName(); - } - }; - - - private ExternalAuthenticationManager() + ExternalAuthenticationManager() { } @@ -137,15 +66,13 @@ public class ExternalAuthenticationManager implements AuthenticationManager // Process response from the client try { - byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]); + server.evaluateResponse(response != null ? response : new byte[0]); Principal principal = ((ExternalSaslServer)server).getAuthenticatedPrincipal(); if(principal != null) { - final Subject subject = new Subject(); - subject.getPrincipals().add(principal); - return new AuthenticationResult(subject); + return new AuthenticationResult(principal); } else { @@ -162,16 +89,11 @@ public class ExternalAuthenticationManager implements AuthenticationManager @Override public AuthenticationResult authenticate(String username, String password) { - return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR); + return new AuthenticationResult(new UsernamePrincipal(username)); } @Override public void close() { } - - @Override - public void configure(ConfigurationPlugin config) throws ConfigurationException - { - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java new file mode 100644 index 0000000000..3c3628e9db --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java @@ -0,0 +1,40 @@ +/* + * 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 java.util.Map; + +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; + +public class ExternalAuthenticationManagerFactory implements AuthenticationManagerFactory +{ + public static final String PROVIDER_TYPE = ExternalAuthenticationManager.class.getSimpleName(); + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE))) + { + return new ExternalAuthenticationManager(); + } + return null; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java deleted file mode 100644 index 485ca2e1e9..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java +++ /dev/null @@ -1,59 +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 java.net.SocketAddress; - -import java.util.Map; -import org.apache.qpid.common.Closeable; -import org.apache.qpid.server.virtualhost.VirtualHost; - -/** - * Registry for {@link AuthenticationManager} instances. - * - * <p>A lookup method {@link #getAuthenticationManager(SocketAddress)} allows a caller to determine - * the AuthenticationManager associated with a particular port number.</p> - * - * <p>It is important to {@link #close()} the registry after use and this allows the AuthenticationManagers - * to reverse any security registrations they have performed.</p> - */ -public interface IAuthenticationManagerRegistry extends Closeable -{ - /** - * Returns the {@link AuthenticationManager} associated with a particular {@link SocketAddress}. - * If no authentication manager is associated with this address, a default authentication manager will be - * returned. Null is never returned. - * - * @param address - * @return authentication manager. - */ - public AuthenticationManager getAuthenticationManager(SocketAddress address); - - Map<String, AuthenticationManager> getAvailableAuthenticationManagers(); - - public static interface RegistryChangeListener - { - void authenticationManagerRegistered(AuthenticationManager authenticationManager); - void authenticationManagerUnregistered(AuthenticationManager authenticationManager); - } - - public void addRegistryChangeListener(RegistryChangeListener listener); - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java index d735ecb1d4..3c1b709648 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java @@ -20,10 +20,7 @@ package org.apache.qpid.server.security.auth.manager; import java.io.IOException; import java.security.Principal; -import java.util.Arrays; import java.util.HashMap; -import java.util.List; -import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; @@ -31,86 +28,15 @@ import javax.security.sasl.AuthorizeCallback; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.UsernamePrincipal; public class KerberosAuthenticationManager implements AuthenticationManager { - private static final Logger _logger = Logger.getLogger(KerberosAuthenticationManager.class); - private static final String GSSAPI_MECHANISM = "GSSAPI"; private final CallbackHandler _callbackHandler = new GssApiCallbackHandler(); - public static class KerberosAuthenticationManagerConfiguration extends ConfigurationPlugin - { - - public static final ConfigurationPluginFactory FACTORY = - new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.kerberos-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new KerberosAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[0]; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - } - - - public static final AuthenticationManagerPluginFactory<KerberosAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<KerberosAuthenticationManager>() - { - public KerberosAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - KerberosAuthenticationManagerConfiguration configuration = - config == null - ? null - : (KerberosAuthenticationManagerConfiguration) config.getConfiguration(KerberosAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for KerberosAuthenticationManager"); - return null; - } - KerberosAuthenticationManager kerberosAuthenticationManager = new KerberosAuthenticationManager(); - kerberosAuthenticationManager.configure(configuration); - return kerberosAuthenticationManager; - } - - public Class<KerberosAuthenticationManager> getPluginClass() - { - return KerberosAuthenticationManager.class; - } - - public String getPluginName() - { - return KerberosAuthenticationManager.class.getName(); - } - }; - - - private KerberosAuthenticationManager() + KerberosAuthenticationManager() { } @@ -158,10 +84,7 @@ public class KerberosAuthenticationManager implements AuthenticationManager if (server.isComplete()) { - final Subject subject = new Subject(); - _logger.debug("Authenticated as " + server.getAuthorizationID()); - subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID())); - return new AuthenticationResult(subject); + return new AuthenticationResult(new UsernamePrincipal(server.getAuthorizationID())); } else { @@ -186,11 +109,6 @@ public class KerberosAuthenticationManager implements AuthenticationManager { } - @Override - public void configure(ConfigurationPlugin config) throws ConfigurationException - { - } - private static class GssApiCallbackHandler implements CallbackHandler { diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java new file mode 100644 index 0000000000..7af6727280 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java @@ -0,0 +1,39 @@ +/* + * 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 java.util.Map; + +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; + +public class KerberosAuthenticationManagerFactory implements AuthenticationManagerFactory +{ + public static final String PROVIDER_TYPE = KerberosAuthenticationManager.class.getSimpleName(); + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE))) + { + return new KerberosAuthenticationManager(); + } + return null; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java index a51f195761..43b92735f1 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java @@ -20,13 +20,23 @@ */ package org.apache.qpid.server.security.auth.manager; -import org.apache.qpid.server.plugins.PluginFactory; +import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase; +import org.apache.qpid.server.security.auth.database.PrincipalDatabase; -/** - * Factory producing authentication producing configured, initialised authentication - * managers. - */ -public interface AuthenticationManagerPluginFactory<S extends AuthenticationManager> extends PluginFactory<S> +public class PlainPasswordFileAuthenticationManagerFactory extends AbstractPrincipalDatabaseAuthManagerFactory { + public static final String PROVIDER_TYPE = "PlainPasswordFileAuthenticationProvider"; + + @Override + String getType() + { + return PROVIDER_TYPE; + } + + @Override + PrincipalDatabase createPrincipalDatabase() + { + return new PlainPasswordFilePrincipalDatabase(); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java index e6498919a1..f4c834810d 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java @@ -21,38 +21,25 @@ package org.apache.qpid.server.security.auth.manager; import java.security.Principal; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; -import org.apache.qpid.configuration.PropertyException; -import org.apache.qpid.configuration.PropertyUtils; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import org.apache.qpid.server.security.auth.AuthenticationResult; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser; import org.apache.qpid.server.security.auth.sasl.JCAProvider; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.UsernamePrincipal; -import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.AccountNotFoundException; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import javax.security.sasl.SaslServerFactory; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; + import java.security.Security; -import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; -import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.TreeMap; @@ -60,27 +47,10 @@ import java.util.TreeMap; * Concrete implementation of the AuthenticationManager that determines if supplied * user credentials match those appearing in a PrincipalDatabase. The implementation * of the PrincipalDatabase is determined from the configuration. - * - * This implementation also registers the JMX UserManagemement MBean. - * - * This plugin expects configuration such as: - * - * <pre> - * <pd-auth-manager> - * <principal-database> - * <class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class> - * <attributes> - * <attribute> - * <name>passwordFile</name> - * <value>${conf}/passwd</value> - * </attribute> - * </attributes> - * </principal-database> - * </pd-auth-manager> - * </pre> */ public class PrincipalDatabaseAuthenticationManager implements AuthenticationManager { + private static final Logger _logger = Logger.getLogger(PrincipalDatabaseAuthenticationManager.class); /** The list of mechanisms, in the order in which they are configured (i.e. preferred order) */ @@ -95,95 +65,11 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan */ private final Map<String, Map<String, ?>> _serverCreationProperties = new HashMap<String, Map<String, ?>>(); - private PrincipalDatabase _principalDatabase = null; + private final PrincipalDatabase _principalDatabase; - public static final AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager>() - { - public PrincipalDatabaseAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - final PrincipalDatabaseAuthenticationManagerConfiguration configuration = - config == null - ? null - : (PrincipalDatabaseAuthenticationManagerConfiguration) config.getConfiguration(PrincipalDatabaseAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for PrincipalDatabaseAuthenticationManager"); - return null; - } - - final PrincipalDatabaseAuthenticationManager pdam = new PrincipalDatabaseAuthenticationManager(); - pdam.configure(configuration); - pdam.initialise(); - return pdam; - } - - public Class<PrincipalDatabaseAuthenticationManager> getPluginClass() - { - return PrincipalDatabaseAuthenticationManager.class; - } - - public String getPluginName() - { - return PrincipalDatabaseAuthenticationManager.class.getName(); - } - }; - - public static class PrincipalDatabaseAuthenticationManagerConfiguration extends ConfigurationPlugin { - - public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.pd-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new PrincipalDatabaseAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[] {"principal-database.class", - "principal-database.attributes.attribute.name", - "principal-database.attributes.attribute.value"}; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - public String getPrincipalDatabaseClass() - { - return getConfig().getString("principal-database.class"); - } - - public Map<String,String> getPdClassAttributeMap() throws ConfigurationException - { - final List<String> argumentNames = (List) getConfig().getList("principal-database.attributes.attribute.name"); - final List<String> argumentValues = (List) getConfig().getList("principal-database.attributes.attribute.value"); - final Map<String,String> attributes = new HashMap<String,String>(argumentNames.size()); - - for (int i = 0; i < argumentNames.size(); i++) - { - final String argName = argumentNames.get(i); - final String argValue = argumentValues.get(i); - - attributes.put(argName, argValue); - } - - return Collections.unmodifiableMap(attributes); - } - } - - protected PrincipalDatabaseAuthenticationManager() + public PrincipalDatabaseAuthenticationManager(PrincipalDatabase pd) { + _principalDatabase = pd; } public void initialise() @@ -246,21 +132,6 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan _logger.info("Initialised " + mechanism + " SASL provider successfully"); } - /** - * @see org.apache.qpid.server.plugins.Plugin#configure(org.apache.qpid.server.configuration.plugins.ConfigurationPlugin) - */ - public void configure(final ConfigurationPlugin config) throws ConfigurationException - { - final PrincipalDatabaseAuthenticationManagerConfiguration pdamConfig = (PrincipalDatabaseAuthenticationManagerConfiguration) config; - final String pdClazz = pdamConfig.getPrincipalDatabaseClass(); - - _logger.info("PrincipalDatabase concrete implementation : " + pdClazz); - - _principalDatabase = createPrincipalDatabaseImpl(pdClazz); - - configPrincipalDatabase(_principalDatabase, pdamConfig); - } - public String getMechanisms() { return _mechanisms; @@ -268,8 +139,11 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException { - return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, _serverCreationProperties.get(mechanism), - _callbackHandlerMap.get(mechanism)); + Map<String, ?> properties = _serverCreationProperties.get(mechanism); + CallbackHandler callbackHandler = _callbackHandlerMap.get(mechanism); + + return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, properties, + callbackHandler); } /** @@ -284,9 +158,8 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan if (server.isComplete()) { - final Subject subject = new Subject(); - subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID())); - return new AuthenticationResult(subject); + final String userId = server.getAuthorizationID(); + return new AuthenticationResult(new UsernamePrincipal(userId)); } else { @@ -308,9 +181,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan { if (_principalDatabase.verifyPassword(username, password.toCharArray())) { - final Subject subject = new Subject(); - subject.getPrincipals().add(new UsernamePrincipal(username)); - return new AuthenticationResult(subject); + return new AuthenticationResult(new UsernamePrincipal(username)); } else { @@ -329,100 +200,8 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan Security.removeProvider(PROVIDER_NAME); } - private PrincipalDatabase createPrincipalDatabaseImpl(final String pdClazz) throws ConfigurationException - { - try - { - return (PrincipalDatabase) Class.forName(pdClazz).newInstance(); - } - catch (InstantiationException ie) - { - throw new ConfigurationException("Cannot instantiate " + pdClazz, ie); - } - catch (IllegalAccessException iae) - { - throw new ConfigurationException("Cannot access " + pdClazz, iae); - } - catch (ClassNotFoundException cnfe) - { - throw new ConfigurationException("Cannot load " + pdClazz + " implementation", cnfe); - } - catch (ClassCastException cce) - { - throw new ConfigurationException("Expecting a " + PrincipalDatabase.class + " implementation", cce); - } - } - - private void configPrincipalDatabase(final PrincipalDatabase principalDatabase, final PrincipalDatabaseAuthenticationManagerConfiguration config) - throws ConfigurationException - { - - final Map<String,String> attributes = config.getPdClassAttributeMap(); - - for (Iterator<Entry<String, String>> iterator = attributes.entrySet().iterator(); iterator.hasNext();) - { - final Entry<String, String> nameValuePair = iterator.next(); - final String methodName = generateSetterName(nameValuePair.getKey()); - final Method method; - try - { - method = principalDatabase.getClass().getMethod(methodName, String.class); - } - catch (Exception e) - { - throw new ConfigurationException("No method " + methodName + " found in class " - + principalDatabase.getClass() - + " hence unable to configure principal database. The method must be public and " - + "have a single String argument with a void return type", e); - } - try - { - method.invoke(principalDatabase, PropertyUtils.replaceProperties(nameValuePair.getValue())); - } - catch (IllegalArgumentException e) - { - throw new ConfigurationException(e.getMessage(), e); - } - catch (PropertyException e) - { - throw new ConfigurationException(e.getMessage(), e); - } - catch (IllegalAccessException e) - { - throw new ConfigurationException(e.getMessage(), e); - } - catch (InvocationTargetException e) - { - // QPID-1347.. InvocationTargetException wraps the checked exception thrown from the reflective - // method call. Pull out the underlying message and cause to make these more apparent to the user. - throw new ConfigurationException(e.getCause().getMessage(), e.getCause()); - } - } - } - public PrincipalDatabase getPrincipalDatabase() { return _principalDatabase; } - - private String generateSetterName(String argName) throws ConfigurationException - { - if ((argName == null) || (argName.length() == 0)) - { - throw new ConfigurationException("Argument names must have length >= 1 character"); - } - - if (Character.isLowerCase(argName.charAt(0))) - { - argName = Character.toUpperCase(argName.charAt(0)) + argName.substring(1); - } - - final String methodName = "set" + argName; - return methodName; - } - - protected void setPrincipalDatabase(final PrincipalDatabase principalDatabase) - { - _principalDatabase = principalDatabase; - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java index 64b24e28bc..7891ef8cf5 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java @@ -21,10 +21,10 @@ package org.apache.qpid.server.security.auth.manager; import java.io.IOException; import java.security.Principal; -import java.util.Arrays; import java.util.HashMap; import java.util.Hashtable; -import java.util.List; + +import javax.naming.AuthenticationException; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; @@ -32,7 +32,6 @@ import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; -import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; @@ -41,13 +40,10 @@ import javax.security.sasl.AuthorizeCallback; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.sasl.plain.PlainPasswordCallback; public class SimpleLDAPAuthenticationManager implements AuthenticationManager @@ -55,123 +51,25 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager private static final Logger _logger = Logger.getLogger(SimpleLDAPAuthenticationManager.class); private static final String PLAIN_MECHANISM = "PLAIN"; - private static final String DEFAULT_LDAP_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory"; - private String _providerSearchURL; - private String _searchContext; - private String _searchFilter; - private String _providerAuthURL; - private String _ldapContextFactory; - - public static class SimpleLDAPAuthenticationManagerConfiguration extends ConfigurationPlugin - { - - public static final ConfigurationPluginFactory FACTORY = - new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.simple-ldap-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new SimpleLDAPAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - private static final String PROVIDER_URL = "provider-url"; - private static final String PROVIDER_SEARCH_URL = "provider-search-url"; - private static final String PROVIDER_AUTH_URL = "provider-auth-url"; - private static final String SEARCH_CONTEXT = "search-context"; - private static final String SEARCH_FILTER = "search-filter"; - private static final String LDAP_CONTEXT_FACTORY = "ldap-context-factory"; - - public String[] getElementsProcessed() - { - return new String[] {PROVIDER_URL, PROVIDER_SEARCH_URL, PROVIDER_AUTH_URL, SEARCH_CONTEXT, SEARCH_FILTER, - LDAP_CONTEXT_FACTORY}; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - public String getLDAPContextFactory() - { - return getConfig().getString(LDAP_CONTEXT_FACTORY, DEFAULT_LDAP_CONTEXT_FACTORY); - } - - - public String getProviderURL() - { - return getConfig().getString(PROVIDER_URL); - } - - public String getProviderSearchURL() - { - return getConfig().getString(PROVIDER_SEARCH_URL, getProviderURL()); - } - - public String getSearchContext() - { - return getConfig().getString(SEARCH_CONTEXT); - } - - public String getSearchFilter() - { - return getConfig().getString(SEARCH_FILTER); - } - - public String getProviderAuthURL() - { - return getConfig().getString(PROVIDER_AUTH_URL, getProviderURL()); - } - } - - - public static final AuthenticationManagerPluginFactory<SimpleLDAPAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<SimpleLDAPAuthenticationManager>() - { - public SimpleLDAPAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - SimpleLDAPAuthenticationManagerConfiguration configuration = - config == null - ? null - : (SimpleLDAPAuthenticationManagerConfiguration) config.getConfiguration(SimpleLDAPAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for SimpleLDAPAuthenticationManager"); - return null; - } - SimpleLDAPAuthenticationManager simpleLDAPAuthenticationManager = new SimpleLDAPAuthenticationManager(); - simpleLDAPAuthenticationManager.configure(configuration); - return simpleLDAPAuthenticationManager; - } - - public Class<SimpleLDAPAuthenticationManager> getPluginClass() - { - return SimpleLDAPAuthenticationManager.class; - } - - public String getPluginName() - { - return SimpleLDAPAuthenticationManager.class.getName(); - } - }; - + private final String _providerSearchURL; + private final String _providerAuthURL; + private final String _searchContext; + private final String _searchFilter; + private final String _ldapContextFactory; - private SimpleLDAPAuthenticationManager() + SimpleLDAPAuthenticationManager(String providerSearchUrl, String providerAuthUrl, String searchContext, String searchFilter, String ldapContextFactory) { + _providerSearchURL = providerSearchUrl; + _providerAuthURL = providerAuthUrl; + _searchContext = searchContext; + _searchFilter = searchFilter; + _ldapContextFactory = ldapContextFactory; } @Override public void initialise() { - + validateInitialDirContext(); } @Override @@ -205,10 +103,10 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager if (server.isComplete()) { - final Subject subject = new Subject(); - _logger.debug("Authenticated as " + server.getAuthorizationID()); - subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID())); - return new AuthenticationResult(subject); + String authorizationID = server.getAuthorizationID(); + _logger.debug("Authenticated as " + authorizationID); + + return new AuthenticationResult(new UsernamePrincipal(authorizationID)); } else { @@ -224,34 +122,74 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager @Override public AuthenticationResult authenticate(String username, String password) { - try { - return doLDAPNameAuthentication(getNameFromId(username), password); + AuthenticationResult result = doLDAPNameAuthentication(getNameFromId(username), password); + if(result.getStatus() == AuthenticationStatus.SUCCESS) + { + //Return a result based on the supplied username rather than the search name + return new AuthenticationResult(new UsernamePrincipal(username)); + } + else + { + return result; + } } catch (NamingException e) { - return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); - } } - private AuthenticationResult doLDAPNameAuthentication(String username, String password) throws NamingException + private AuthenticationResult doLDAPNameAuthentication(String name, String password) { + if(name == null) + { + //The search didn't return anything, class as not-authenticated before it NPEs below + return new AuthenticationResult(AuthenticationStatus.CONTINUE); + } + Hashtable<Object,Object> env = new Hashtable<Object,Object>(); env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory); env.put(Context.PROVIDER_URL, _providerAuthURL); env.put(Context.SECURITY_AUTHENTICATION, "simple"); - env.put(Context.SECURITY_PRINCIPAL, username); + env.put(Context.SECURITY_PRINCIPAL, name); env.put(Context.SECURITY_CREDENTIALS, password); - DirContext ctx = new InitialDirContext(env); - ctx.close(); - final Subject subject = new Subject(); - subject.getPrincipals().add(new UsernamePrincipal(username)); - return new AuthenticationResult(subject); + + DirContext ctx = null; + try + { + ctx = new InitialDirContext(env); + + //Authentication succeeded + return new AuthenticationResult(new UsernamePrincipal(name)); + } + catch(AuthenticationException ae) + { + //Authentication failed + return new AuthenticationResult(AuthenticationStatus.CONTINUE); + } + catch (NamingException e) + { + //Some other failure + return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); + } + finally + { + if(ctx != null) + { + try + { + ctx.close(); + } + catch (Exception e) + { + _logger.warn("Exception closing InitialDirContext", e); + } + } + } } @Override @@ -259,17 +197,8 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager { } - @Override - public void configure(ConfigurationPlugin config) throws ConfigurationException + private void validateInitialDirContext() { - SimpleLDAPAuthenticationManagerConfiguration ldapConfig = (SimpleLDAPAuthenticationManagerConfiguration) config; - - _ldapContextFactory = ldapConfig.getLDAPContextFactory(); - _providerSearchURL = ldapConfig.getProviderSearchURL(); - _providerAuthURL = ldapConfig.getProviderAuthURL(); - _searchContext = ldapConfig.getSearchContext(); - _searchFilter = ldapConfig.getSearchFilter(); - Hashtable<String,Object> env = new Hashtable<String, Object>(); env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory); env.put(Context.PROVIDER_URL, _providerSearchURL); @@ -277,11 +206,11 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager try { - new InitialDirContext(env); + new InitialDirContext(env).close(); } catch (NamingException e) { - throw new ConfigurationException("Unable to establish anonymous connection to the ldap server at " + _providerSearchURL, e); + throw new RuntimeException("Unable to establish anonymous connection to the ldap server at " + _providerSearchURL, e); } } @@ -305,19 +234,11 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager } catch (NamingException e) { - _logger.info("SASL Authentication Error", e); + _logger.warn("SASL Authentication Exception", e); } if(password != null) { - try - { - authenticated = doLDAPNameAuthentication(name, password); - - } - catch (NamingException e) - { - authenticated = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); - } + authenticated = doLDAPNameAuthentication(name, password); } } else if (callback instanceof PlainPasswordCallback) @@ -325,17 +246,10 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager password = ((PlainPasswordCallback)callback).getPlainPassword(); if(name != null) { - try - { - authenticated = doLDAPNameAuthentication(name, password); - if(authenticated.getStatus()== AuthenticationResult.AuthenticationStatus.SUCCESS) - { - ((PlainPasswordCallback)callback).setAuthenticated(true); - } - } - catch (NamingException e) + authenticated = doLDAPNameAuthentication(name, password); + if(authenticated.getStatus()== AuthenticationResult.AuthenticationStatus.SUCCESS) { - authenticated = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); + ((PlainPasswordCallback)callback).setAuthenticated(true); } } } @@ -357,7 +271,6 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory); env.put(Context.PROVIDER_URL, _providerSearchURL); - env.put(Context.SECURITY_AUTHENTICATION, "none"); DirContext ctx = null; @@ -382,7 +295,14 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager } finally { - ctx.close(); + try + { + ctx.close(); + } + catch (Exception e) + { + _logger.warn("Exception closing InitialDirContext", e); + } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java new file mode 100644 index 0000000000..05a692fb0e --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java @@ -0,0 +1,69 @@ +/* + * 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 java.util.Map; + +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; + +public class SimpleLDAPAuthenticationManagerFactory implements AuthenticationManagerFactory +{ + private static final String DEFAULT_LDAP_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory"; + + public static final String PROVIDER_TYPE = SimpleLDAPAuthenticationManager.class.getSimpleName(); + + public static final String ATTRIBUTE_LDAP_CONTEXT_FACTORY = "ldapContextFactory"; + public static final String ATTRIBUTE_SEARCH_FILTER = "searchFilter"; + public static final String ATTRIBUTE_SEARCH_CONTEXT = "searchContext"; + public static final String ATTRIBUTE_PROVIDER_AUTH_URL = "providerAuthUrl"; + public static final String ATTRIBUTE_PROVIDER_SEARCH_URL = "providerSearchUrl"; + public static final String ATTRIBUTE_PROVIDER_URL = "providerUrl"; + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes == null || !PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE))) + { + return null; + } + String providerUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_URL); + String providerSearchUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_SEARCH_URL); + if (providerSearchUrl == null) + { + providerSearchUrl = providerUrl; + } + String providerAuthUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_AUTH_URL); + if (providerAuthUrl == null) + { + providerAuthUrl = providerUrl; + } + String searchContext = (String) attributes.get(ATTRIBUTE_SEARCH_CONTEXT); + String searchFilter = (String) attributes.get(ATTRIBUTE_SEARCH_FILTER); + String ldapContextFactory = (String) attributes.get(ATTRIBUTE_LDAP_CONTEXT_FACTORY); + if (ldapContextFactory == null) + { + ldapContextFactory = DEFAULT_LDAP_CONTEXT_FACTORY; + } + + return new SimpleLDAPAuthenticationManager(providerSearchUrl, providerAuthUrl, searchContext, searchFilter, + ldapContextFactory); + } + +} |