diff options
| author | Robert Godfrey <rgodfrey@apache.org> | 2012-05-17 20:15:22 +0000 |
|---|---|---|
| committer | Robert Godfrey <rgodfrey@apache.org> | 2012-05-17 20:15:22 +0000 |
| commit | f9ede019aff893addfc8a056da8681c59ad53959 (patch) | |
| tree | 4e04944faf9f0b7e2fc8948295040b4c279ebc99 /qpid/java | |
| parent | 7f1485ca76ddd55c0408b81b3e9425322395a396 (diff) | |
| download | qpid-python-f9ede019aff893addfc8a056da8681c59ad53959.tar.gz | |
QPID-4007 : [Java Broker] Add Kerberos authentication support
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1339840 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java')
2 files changed, 230 insertions, 2 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java index 5c49752ede..9b3efe197a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java @@ -23,6 +23,7 @@ import org.apache.felix.framework.Felix; import org.apache.felix.framework.util.StringMap; import org.apache.log4j.Logger; import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager; +import org.apache.qpid.server.security.auth.manager.KerberosAuthenticationManager; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; @@ -158,7 +159,8 @@ public class PluginManager implements Closeable new SlowConsumerDetectionPolicyConfigurationFactory(), new SlowConsumerDetectionQueueConfigurationFactory(), PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration.FACTORY, - AnonymousAuthenticationManager.AnonymousAuthenticationManagerConfiguration.FACTORY)) + AnonymousAuthenticationManager.AnonymousAuthenticationManagerConfiguration.FACTORY, + KerberosAuthenticationManager.KerberosAuthenticationManagerConfiguration.FACTORY)) { _configPlugins.put(configFactory.getParentPaths(), configFactory); } @@ -174,7 +176,8 @@ public class PluginManager implements Closeable } for (AuthenticationManagerPluginFactory<? extends Plugin> pluginFactory : Arrays.asList( - PrincipalDatabaseAuthenticationManager.FACTORY, AnonymousAuthenticationManager.FACTORY)) + PrincipalDatabaseAuthenticationManager.FACTORY, AnonymousAuthenticationManager.FACTORY, + KerberosAuthenticationManager.FACTORY)) { _authenticationManagerPlugins.put(pluginFactory.getPluginName(), pluginFactory); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java new file mode 100644 index 0000000000..47de1151ea --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java @@ -0,0 +1,225 @@ +/* + * 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.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; +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; + +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 AnonymousAuthenticationManager"); + 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() + { + } + + @Override + public void initialise() + { + + } + + @Override + public String getMechanisms() + { + return GSSAPI_MECHANISM; + } + + @Override + public SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException + { + if(mechanism.equals(mechanism)) + { + try + { + return Sasl.createSaslServer(GSSAPI_MECHANISM, "AMQP", "scrumpy", + new HashMap<String, Object>(), _callbackHandler); + } + catch (SaslException e) + { + e.printStackTrace(System.err); + throw e; + } + } + else + { + throw new SaslException("Unknown mechanism: " + mechanism); + } + } + + @Override + public AuthenticationResult authenticate(SaslServer server, byte[] response) + { + try + { + // Process response from the client + byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]); + + 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); + } + else + { + return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.CONTINUE); + } + } + catch (SaslException e) + { + e.printStackTrace(System.err); + return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); + } + } + + @Override + public AuthenticationResult authenticate(String username, String password) + { + return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR); + } + + @Override + public CallbackHandler getHandler(String mechanism) + { + if(GSSAPI_MECHANISM.equals(mechanism)) + { + return _callbackHandler; + } + else + { + return null; + } + } + + @Override + public void close() + { + } + + @Override + public void configure(ConfigurationPlugin config) throws ConfigurationException + { + } + + private static class GssApiCallbackHandler implements CallbackHandler + { + + @Override + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException + { + for(Callback callback : callbacks) + { + if (callback instanceof AuthorizeCallback) + { + ((AuthorizeCallback) callback).setAuthorized(true); + } + else + { + throw new UnsupportedCallbackException(callback); + } + } + } + } +} |
