summaryrefslogtreecommitdiff
path: root/java/client/src
diff options
context:
space:
mode:
authorRobert Greig <rgreig@apache.org>2007-02-20 16:51:32 +0000
committerRobert Greig <rgreig@apache.org>2007-02-20 16:51:32 +0000
commit53dfa7e61494fc38de8b527a91dfdb6051260e2a (patch)
tree9c36100358f74974f5c5b544d8c09b5053aa6d6d /java/client/src
parent797b61fa56e3576e4a85780e7e8bdc20e6833d75 (diff)
downloadqpid-python-53dfa7e61494fc38de8b527a91dfdb6051260e2a.tar.gz
(Path submitted by Rupert Smith) Qpid-338. Custom SASL implementation for Java 1.4 retrotranslation of the Java client.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@509642 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/client/src')
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java71
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.java103
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java99
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties4
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java36
5 files changed, 245 insertions, 68 deletions
diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
index 66ae92113c..2aa2c1872b 100644
--- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
+++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
@@ -29,6 +29,7 @@ import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.client.protocol.AMQProtocolSession;
import org.apache.qpid.client.security.AMQCallbackHandler;
@@ -48,7 +49,6 @@ import org.apache.qpid.protocol.AMQMethodEvent;
public class ConnectionStartMethodHandler implements StateAwareMethodListener
{
-
private static final Logger _log = Logger.getLogger(ConnectionStartMethodHandler.class);
private static final ConnectionStartMethodHandler _instance = new ConnectionStartMethodHandler();
@@ -59,19 +59,23 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener
}
private ConnectionStartMethodHandler()
- {
- }
+ { }
- public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException
+ public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt)
+ throws AMQException
{
+ _log.debug("public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, "
+ + "AMQMethodEvent evt): called");
+
ConnectionStartBody body = (ConnectionStartBody) evt.getMethod();
byte major = (byte) body.versionMajor;
byte minor = (byte) body.versionMinor;
boolean versionOk = false;
- // for the purposes of interop, we can make the client accept the broker's version string.
- // if it does, it then internally records the version as being the latest one that it understands.
- // it needs to do this since frame lookup is done by version.
+
+ // For the purposes of interop, we can make the client accept the broker's version string.
+ // If it does, it then internally records the version as being the latest one that it understands.
+ // It needs to do this since frame lookup is done by version.
if (Boolean.getBoolean("qpid.accept.broker.version"))
{
versionOk = true;
@@ -90,8 +94,9 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener
try
{
- // the mechanism we are going to use
+ // Used to hold the SASL mechanism to authenticate with.
String mechanism;
+
if (body.mechanisms == null)
{
throw new AMQException("mechanism not specified in ConnectionStart method frame");
@@ -99,6 +104,7 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener
else
{
mechanism = chooseMechanism(body.mechanisms);
+ _log.debug("mechanism = " + mechanism);
}
if (mechanism == null)
@@ -109,15 +115,17 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener
byte[] saslResponse;
try
{
- SaslClient sc = Sasl.createSaslClient(new String[]{mechanism},
- null, "AMQP", "localhost",
- null,createCallbackHandler(mechanism, protocolSession));
+ SaslClient sc =
+ Sasl.createSaslClient(new String[] { mechanism }, null, "AMQP", "localhost", null,
+ createCallbackHandler(mechanism, protocolSession));
if (sc == null)
{
- throw new AMQException("Client SASL configuration error: no SaslClient could be created for mechanism " +
- mechanism + ". Please ensure all factories are registered. See DynamicSaslRegistrar for " +
- " details of how to register non-standard SASL client providers.");
+ throw new AMQException(
+ "Client SASL configuration error: no SaslClient could be created for mechanism " + mechanism
+ + ". Please ensure all factories are registered. See DynamicSaslRegistrar for "
+ + " details of how to register non-standard SASL client providers.");
}
+
protocolSession.setSaslClient(sc);
saslResponse = (sc.hasInitialResponse() ? sc.evaluateChallenge(new byte[0]) : null);
}
@@ -131,6 +139,7 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener
{
throw new AMQException("Locales is not defined in Connection Start method");
}
+
final String locales = new String(body.locales, "utf8");
final StringTokenizer tokenizer = new StringTokenizer(locales, " ");
String selectedLocale = null;
@@ -146,21 +155,24 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener
stateManager.changeState(AMQState.CONNECTION_NOT_TUNED);
FieldTable clientProperties = FieldTableFactory.newFieldTable();
- clientProperties.setString(new AMQShortString(ClientProperties.instance.toString()), protocolSession.getClientID());
- clientProperties.setString(new AMQShortString(ClientProperties.product.toString()), QpidProperties.getProductName());
- clientProperties.setString(new AMQShortString(ClientProperties.version.toString()), QpidProperties.getReleaseVersion());
+ clientProperties.setString(new AMQShortString(ClientProperties.instance.toString()),
+ protocolSession.getClientID());
+ clientProperties.setString(new AMQShortString(ClientProperties.product.toString()),
+ QpidProperties.getProductName());
+ clientProperties.setString(new AMQShortString(ClientProperties.version.toString()),
+ QpidProperties.getReleaseVersion());
clientProperties.setString(new AMQShortString(ClientProperties.platform.toString()), getFullSystemInfo());
// AMQP version change: Hardwire the version to 0-8 (major=8, minor=0)
// TODO: Connect this to the session version obtained from ProtocolInitiation for this session.
// Be aware of possible changes to parameter order as versions change.
protocolSession.writeFrame(ConnectionStartOkBody.createAMQFrame(evt.getChannelId(),
- protocolSession.getProtocolMajorVersion(),
- protocolSession.getProtocolMinorVersion(),
- clientProperties, // clientProperties
- new AMQShortString(selectedLocale), // locale
- new AMQShortString(mechanism), // mechanism
- saslResponse)); // response
+ protocolSession.getProtocolMajorVersion(),
+ protocolSession.getProtocolMinorVersion(),
+ clientProperties, // clientProperties
+ new AMQShortString(selectedLocale), // locale
+ new AMQShortString(mechanism), // mechanism
+ saslResponse)); // response
}
catch (UnsupportedEncodingException e)
@@ -170,11 +182,8 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener
}
else
{
- _log.error("Broker requested Protocol ["
- + body.versionMajor
- + "-"
- + body.versionMinor
- + "] which is not supported by this version of the client library");
+ _log.error("Broker requested Protocol [" + body.versionMajor + "-" + body.versionMinor
+ + "] which is not supported by this version of the client library");
protocolSession.closeProtocolSession();
}
@@ -185,7 +194,7 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener
byte[][] supportedVersions = ProtocolVersionList.pv;
boolean supported = false;
int i = supportedVersions.length;
- while(i-- != 0 && !supported)
+ while ((i-- != 0) && !supported)
{
supported = (supportedVersions[i][ProtocolVersionList.PROTOCOL_MAJOR] == versionMajor)
&& (supportedVersions[i][ProtocolVersionList.PROTOCOL_MINOR] == versionMinor);
@@ -228,11 +237,12 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener
return mech;
}
}
+
return null;
}
private AMQCallbackHandler createCallbackHandler(String mechanism, AMQProtocolSession protocolSession)
- throws AMQException
+ throws AMQException
{
Class mechanismClass = CallbackHandlerRegistry.getInstance().getCallbackHandlerClass(mechanism);
try
@@ -240,6 +250,7 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener
Object instance = mechanismClass.newInstance();
AMQCallbackHandler cbh = (AMQCallbackHandler) instance;
cbh.initialise(protocolSession);
+
return cbh;
}
catch (Exception e)
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.java b/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.java
index bcf77e1586..5c0f1de5bb 100644
--- a/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.java
+++ b/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.java
@@ -7,9 +7,9 @@
* 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
@@ -33,45 +33,102 @@ import java.util.Properties;
import org.apache.log4j.Logger;
+import org.apache.qpid.util.FileUtils;
+
+/**
+ * CallbackHandlerRegistry is a registry for call back handlers for user authentication and interaction during user
+ * authentication. It is capable of reading its configuration from a properties file containing call back handler
+ * implementing class names for different SASL mechanism names. Instantiating this registry also has the effect of
+ * configuring and registering the SASL client factory implementations using {@link DynamicSaslRegistrar}.
+ *
+ * <p/>The callback configuration should be specified in a properties file, refered to by the System property
+ * "amp.callbackhandler.properties". The format of the properties file is:
+ *
+ * <p/><pre>
+ * CallbackHanlder.mechanism=fully.qualified.class.name
+ * </pre>
+ *
+ * <p/>Where mechanism is an IANA-registered mechanism name and the fully qualified class name refers to a
+ * class that implements org.apache.qpid.client.security.AMQCallbackHanlder and provides a call back handler for the
+ * specified mechanism.
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Parse callback properties.
+ * <tr><td> Provide mapping from SASL mechanisms to callback implementations.
+ * </table>
+ */
public class CallbackHandlerRegistry
{
+ private static final Logger _logger = Logger.getLogger(CallbackHandlerRegistry.class);
+
+ /** The name of the system property that holds the name of the callback handler properties file. */
private static final String FILE_PROPERTY = "amq.callbackhandler.properties";
- private static final Logger _logger = Logger.getLogger(CallbackHandlerRegistry.class);
+ /** The default name of the callback handler properties resource. */
+ public static final String DEFAULT_RESOURCE_NAME = "org/apache/qpid/client/security/CallbackHandlerRegistry.properties";
+ /** A static reference to the singleton instance of this registry. */
private static CallbackHandlerRegistry _instance = new CallbackHandlerRegistry();
- private Map _mechanismToHandlerClassMap = new HashMap();
+ /** Holds a map from SASL mechanism names to call back handlers. */
+ private Map<String, Class> _mechanismToHandlerClassMap = new HashMap<String, Class>();
+ /** Holds a space delimited list of mechanisms that callback handlers exist for. */
private String _mechanisms;
+ /**
+ * Gets the singleton instance of this registry.
+ *
+ * @return The singleton instance of this registry.
+ */
public static CallbackHandlerRegistry getInstance()
{
- return _instance;
+ return _instance;
}
+ /**
+ * Gets the callback handler class for a given SASL mechanism name.
+ *
+ * @param mechanism The SASL mechanism name.
+ *
+ * @return The callback handler class for the mechanism, or null if none is configured for that mechanism.
+ */
public Class getCallbackHandlerClass(String mechanism)
{
return (Class) _mechanismToHandlerClassMap.get(mechanism);
}
+ /**
+ * Gets a space delimited list of supported SASL mechanisms.
+ *
+ * @return A space delimited list of supported SASL mechanisms.
+ */
public String getMechanisms()
{
return _mechanisms;
}
+ /**
+ * Creates the call back handler registry from its configuration resource or file. This also has the side effect
+ * of configuring and registering the SASL client factory implementations using {@link DynamicSaslRegistrar}.
+ */
private CallbackHandlerRegistry()
{
- // first we register any Sasl client factories
+ // Register any configured SASL client factories.
DynamicSaslRegistrar.registerSaslProviders();
- InputStream is = openPropertiesInputStream();
+ String filename = System.getProperty(FILE_PROPERTY);
+ InputStream is =
+ FileUtils.openFileOrDefaultResource(filename, DEFAULT_RESOURCE_NAME,
+ CallbackHandlerRegistry.class.getClassLoader());
+
try
{
Properties props = new Properties();
props.load(is);
parseProperties(props);
- _logger.info("Available SASL mechanisms: " + _mechanisms);
+ _logger.info("Callback handlers available for SASL mechanisms: " + _mechanisms);
}
catch (IOException e)
{
@@ -94,9 +151,8 @@ public class CallbackHandlerRegistry
}
}
- private InputStream openPropertiesInputStream()
+ /*private InputStream openPropertiesInputStream(String filename)
{
- String filename = System.getProperty(FILE_PROPERTY);
boolean useDefault = true;
InputStream is = null;
if (filename != null)
@@ -111,15 +167,23 @@ public class CallbackHandlerRegistry
_logger.error("Unable to read from file " + filename + ": " + e, e);
}
}
-
+
if (useDefault)
{
- is = CallbackHandlerRegistry.class.getResourceAsStream("CallbackHandlerRegistry.properties");
+ is = CallbackHandlerRegistry.class.getResourceAsStream(DEFAULT_RESOURCE_NAME);
}
-
+
return is;
- }
-
+ }*/
+
+ /**
+ * Scans the specified properties as a mapping from IANA registered SASL mechanism to call back handler
+ * implementations, that provide the necessary call back handling for obtaining user log in credentials
+ * during authentication for the specified mechanism, and builds a map from mechanism names to handler
+ * classes.
+ *
+ * @param props
+ */
private void parseProperties(Properties props)
{
Enumeration e = props.propertyNames();
@@ -130,8 +194,10 @@ public class CallbackHandlerRegistry
if (period < 0)
{
_logger.warn("Unable to parse property " + propertyName + " when configuring SASL providers");
+
continue;
}
+
String mechanism = propertyName.substring(period + 1);
String className = props.getProperty(propertyName);
Class clazz = null;
@@ -140,10 +206,12 @@ public class CallbackHandlerRegistry
clazz = Class.forName(className);
if (!AMQCallbackHandler.class.isAssignableFrom(clazz))
{
- _logger.warn("SASL provider " + clazz + " does not implement " + AMQCallbackHandler.class +
- ". Skipping");
+ _logger.warn("SASL provider " + clazz + " does not implement " + AMQCallbackHandler.class
+ + ". Skipping");
+
continue;
}
+
_mechanismToHandlerClassMap.put(mechanism, clazz);
if (_mechanisms == null)
{
@@ -158,6 +226,7 @@ public class CallbackHandlerRegistry
catch (ClassNotFoundException ex)
{
_logger.warn("Unable to load class " + className + ". Skipping that SASL provider");
+
continue;
}
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java b/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
index 078c5e4989..f8ee22a5d9 100644
--- a/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
+++ b/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
@@ -7,9 +7,9 @@
* 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
@@ -36,20 +36,62 @@ import javax.security.sasl.SaslClientFactory;
import org.apache.log4j.Logger;
+import org.apache.qpid.util.FileUtils;
+
+/**
+ * DynamicSaslRegistrar provides a collection of helper methods for reading a configuration file that contains a mapping
+ * from SASL mechanism names to implementing client factory class names and registering a security provider with the
+ * Java runtime system, that uses the configured client factory implementations.
+ *
+ * <p/>The sasl configuration should be specified in a properties file, refered to by the System property
+ * "amp.dynamicsaslregistrar.properties". The format of the properties file is:
+ *
+ * <p/><pre>
+ * mechanism=fully.qualified.class.name
+ * </pre>
+ *
+ * <p/>Where mechanism is an IANA-registered mechanism name and the fully qualified class name refers to a
+ * class that implements javax.security.sasl.SaslClientFactory and provides the specified mechanism.
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Parse SASL mechanism properties.
+ * <tr><td> Create and register security provider for SASL mechanisms.
+ * </table>
+ */
public class DynamicSaslRegistrar
{
+ private static final Logger _logger = Logger.getLogger(DynamicSaslRegistrar.class);
+
+ /** The name of the system property that holds the name of the SASL configuration properties. */
private static final String FILE_PROPERTY = "amq.dynamicsaslregistrar.properties";
- private static final Logger _logger = Logger.getLogger(DynamicSaslRegistrar.class);
+ /** The default name of the SASL properties file resource. */
+ public static final String DEFAULT_RESOURCE_NAME = "org/apache/qpid/client/security/DynamicSaslRegistrar.properties";
+ /**
+ * Reads the properties file, and creates a dynamic security provider to register the SASL implementations
+ * with.
+ */
public static void registerSaslProviders()
{
- InputStream is = openPropertiesInputStream();
+ _logger.debug("public static void registerSaslProviders(): called");
+
+ // Open the SASL properties file, using the default name is one is not specified.
+ String filename = System.getProperty(FILE_PROPERTY);
+ InputStream is =
+ FileUtils.openFileOrDefaultResource(filename, DEFAULT_RESOURCE_NAME,
+ DynamicSaslRegistrar.class.getClassLoader());
+
try
{
Properties props = new Properties();
props.load(is);
+
+ _logger.debug("props = " + props);
+
Map<String, Class<? extends SaslClientFactory>> factories = parseProperties(props);
+
if (factories.size() > 0)
{
Security.addProvider(new JCAProvider(factories));
@@ -77,16 +119,30 @@ public class DynamicSaslRegistrar
}
}
- private static InputStream openPropertiesInputStream()
+ /**
+ * Either attempts to open the specified filename as an input stream, or uses the default SASL configuration
+ * resource.
+ *
+ * @param filename The name of the file to get the SASL properties from, null to use the default.
+ *
+ * @return An input stream to read the dynamic SASL configuration from, or null if one could not be opened.
+ */
+ /*private static InputStream openPropertiesInputStream(String filename)
{
- String filename = System.getProperty(FILE_PROPERTY);
- boolean useDefault = true;
InputStream is = null;
+
+ // Flag to indicate whether the default resource should be used. By default this is true, so that the default
+ // is used when opening the file fails.
+ boolean useDefault = true;
+
+ // Try to open the file if one was specified.
if (filename != null)
{
try
{
is = new BufferedInputStream(new FileInputStream(new File(filename)));
+
+ // Clear the default flag because the file was succesfully opened.
useDefault = false;
}
catch (FileNotFoundException e)
@@ -95,19 +151,35 @@ public class DynamicSaslRegistrar
}
}
+ // Load the default resource if a file was not specified, or if opening the file failed.
if (useDefault)
{
- is = CallbackHandlerRegistry.class.getResourceAsStream("DynamicSaslRegistrar.properties");
+ is = CallbackHandlerRegistry.class.getResourceAsStream(DEFAULT_RESOURCE_NAME);
}
return is;
- }
+ }*/
+ /**
+ * Parses the specified properties as a mapping from IANA registered SASL mechanism names to implementing client
+ * factories. If the client factories cannot be instantiated or do not implement SaslClientFactory then the
+ * properties refering to them are ignored.
+ *
+ * @param props The properties to scan for Sasl client factory implementations.
+ *
+ * @return A map from SASL mechanism names to implementing client factory classes.
+ *
+ * @todo Why tree map here? Do really want mechanisms in alphabetical order? Seems more likely that the declared
+ * order of the mechanisms is intended to be preserved, so that they are registered in the declared order
+ * of preference. Consider LinkedHashMap instead.
+ */
private static Map<String, Class<? extends SaslClientFactory>> parseProperties(Properties props)
{
Enumeration e = props.propertyNames();
+
TreeMap<String, Class<? extends SaslClientFactory>> factoriesToRegister =
- new TreeMap<String, Class<? extends SaslClientFactory>>();
+ new TreeMap<String, Class<? extends SaslClientFactory>>();
+
while (e.hasMoreElements())
{
String mechanism = (String) e.nextElement();
@@ -118,17 +190,18 @@ public class DynamicSaslRegistrar
if (!(SaslClientFactory.class.isAssignableFrom(clazz)))
{
_logger.error("Class " + clazz + " does not implement " + SaslClientFactory.class + " - skipping");
+
continue;
}
+
factoriesToRegister.put(mechanism, (Class<? extends SaslClientFactory>) clazz);
}
catch (Exception ex)
{
- _logger.error("Error instantiating SaslClientFactory calss " + className + " - skipping");
+ _logger.error("Error instantiating SaslClientFactory calss " + className + " - skipping");
}
}
+
return factoriesToRegister;
}
-
-
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties b/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
index ee66664455..c2a7d7928c 100644
--- a/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
+++ b/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
@@ -6,9 +6,9 @@
# 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
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java b/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java
index ff3ead6d42..2fa8dcddde 100644
--- a/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java
+++ b/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java
@@ -7,9 +7,9 @@
* 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
@@ -26,22 +26,46 @@ import java.util.Map;
import javax.security.sasl.SaslClientFactory;
+import org.apache.log4j.Logger;
+
+/**
+ * JCAProvider is a security provider for SASL client factories that is configured from a map of SASL mechanism names
+ * to client factories implementation class names. It is intended that the map of client factories can be read from a
+ * configuration file or other application configuration mechanism.
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Register SASL mechanism implementations.
+ * </table>
+ */
public class JCAProvider extends Provider
{
+ private static final Logger log = Logger.getLogger(JCAProvider.class);
+
+ /**
+ * Creates the security provider with a map from SASL mechanisms to implementing factories.
+ *
+ * @param providerMap The map from SASL mechanims to implementing factory classes.
+ */
public JCAProvider(Map<String, Class<? extends SaslClientFactory>> providerMap)
{
- super("AMQSASLProvider", 1.0, "A JCA provider that registers all " +
- "AMQ SASL providers that want to be registered");
+ super("AMQSASLProvider", 1.0, "A JCA provider that registers all "
+ + "AMQ SASL providers that want to be registered");
register(providerMap);
Security.addProvider(this);
}
+ /**
+ * Registers client factory classes for a map of mechanism names to client factory classes.
+ *
+ * @param providerMap The map from SASL mechanims to implementing factory classes.
+ */
private void register(Map<String, Class<? extends SaslClientFactory>> providerMap)
{
- for (Map.Entry<String, Class<? extends SaslClientFactory>> me :
- providerMap.entrySet())
+ for (Map.Entry<String, Class<? extends SaslClientFactory>> me : providerMap.entrySet())
{
put("SaslClientFactory." + me.getKey(), me.getValue().getName());
+ log.debug("Registered SASL Client factory for " + me.getKey() + " as " + me.getValue().getName());
}
}
}