summaryrefslogtreecommitdiff
path: root/qpid/java/broker/src/main
diff options
context:
space:
mode:
authorRobert Gemmell <robbie@apache.org>2013-04-01 01:36:18 +0000
committerRobert Gemmell <robbie@apache.org>2013-04-01 01:36:18 +0000
commit43d1adbf18e349a430f7777a862407c51ee2c147 (patch)
treef5dea47975bef966f2d6b870bb99dca2de76fbc9 /qpid/java/broker/src/main
parent4286ef13fc5b0f99f517350e6088f92d86aa596b (diff)
downloadqpid-python-43d1adbf18e349a430f7777a862407c51ee2c147.tar.gz
QPID-4676: change External auth provider to create usernames of the form <CN>@<DC1>.<DC2>....<DCN> by default
- Allows for use of SSL Client Authentication in manner more consistent with the C++ broker - Adds 'useFullDN' attribute to the auth provider to allow enabling use of the old behaviour git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1463074 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker/src/main')
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java16
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationProviderAttributeDescriptions.properties19
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.java89
4 files changed, 124 insertions, 7 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java
index 43e0a9f64f..c503549bf2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java
@@ -31,8 +31,11 @@ public class ExternalAuthenticationManager implements AuthenticationManager
{
private static final String EXTERNAL = "EXTERNAL";
- ExternalAuthenticationManager()
+ private boolean _useFullDN = false;
+
+ ExternalAuthenticationManager(boolean useFullDN)
{
+ _useFullDN = useFullDN;
}
@Override
@@ -52,7 +55,7 @@ public class ExternalAuthenticationManager implements AuthenticationManager
{
if(EXTERNAL.equals(mechanism))
{
- return new ExternalSaslServer(externalPrincipal);
+ return new ExternalSaslServer(externalPrincipal, _useFullDN);
}
else
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
index 64acfafc4a..6029674cd3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
@@ -19,22 +19,32 @@
*/
package org.apache.qpid.server.security.auth.manager;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.util.ResourceBundleLoader;
public class ExternalAuthenticationManagerFactory implements AuthenticationManagerFactory
{
+ public static final String RESOURCE_BUNDLE = "org.apache.qpid.server.security.auth.manager.ExternalAuthenticationProviderAttributeDescriptions";
public static final String PROVIDER_TYPE = "External";
+ public static final String ATTRIBUTE_USE_FULL_DN = "useFullDN";
+
+ public static final Collection<String> ATTRIBUTES = Collections.<String> unmodifiableList(Arrays.asList(
+ ATTRIBUTE_TYPE,
+ ATTRIBUTE_USE_FULL_DN));
@Override
public AuthenticationManager createInstance(Map<String, Object> attributes)
{
if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE)))
{
- return new ExternalAuthenticationManager();
+ boolean useFullDN = Boolean.valueOf(String.valueOf(attributes.get(ATTRIBUTE_USE_FULL_DN)));
+
+ return new ExternalAuthenticationManager(useFullDN);
}
return null;
}
@@ -42,7 +52,7 @@ public class ExternalAuthenticationManagerFactory implements AuthenticationManag
@Override
public Collection<String> getAttributeNames()
{
- return Collections.<String>singletonList(ATTRIBUTE_TYPE);
+ return ATTRIBUTES;
}
@Override
@@ -54,7 +64,7 @@ public class ExternalAuthenticationManagerFactory implements AuthenticationManag
@Override
public Map<String, String> getAttributeDescriptions()
{
- return null;
+ return ResourceBundleLoader.getResources(RESOURCE_BUNDLE);
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationProviderAttributeDescriptions.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationProviderAttributeDescriptions.properties
new file mode 100644
index 0000000000..263254e9fe
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationProviderAttributeDescriptions.properties
@@ -0,0 +1,19 @@
+#
+# 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.
+
+useFullDN=Use the full DN as the Username \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.java
index 9c2bca2d0b..509442b14b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.java
@@ -19,19 +19,27 @@
package org.apache.qpid.server.security.auth.sasl.external;
import java.security.Principal;
+
+import javax.security.auth.x500.X500Principal;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
public class ExternalSaslServer implements SaslServer
{
+ private static final Logger LOGGER = Logger.getLogger(ExternalSaslServer.class);
+
public static final String MECHANISM = "EXTERNAL";
private boolean _complete = false;
private final Principal _externalPrincipal;
+ private boolean _useFullDN = false;
- public ExternalSaslServer(Principal externalPrincipal)
+ public ExternalSaslServer(Principal externalPrincipal, boolean useFullDN)
{
+ _useFullDN = useFullDN;
_externalPrincipal = externalPrincipal;
}
@@ -77,6 +85,83 @@ public class ExternalSaslServer implements SaslServer
public Principal getAuthenticatedPrincipal()
{
- return _externalPrincipal;
+ if (_externalPrincipal instanceof X500Principal && !_useFullDN)
+ {
+ // Construct username as <CN>@<DC1>.<DC2>.<DC3>....<DCN>
+
+ String username;
+ String dn = ((X500Principal) _externalPrincipal).getName(X500Principal.RFC2253);
+
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Parsing username from Principal DN: " + dn);
+ }
+
+ if (dn.contains("CN="))
+ {
+ username = dn.substring(dn.indexOf("CN=") + 3, (dn.indexOf(",", dn.indexOf("CN=")) != -1) ? dn.indexOf(",", dn.indexOf("CN=")) : dn.length());
+
+ if (username.isEmpty())
+ {
+ // CN is empty => Cannot construct username => Authentication failed => return null
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("CN value was empty in Principal name, unable to construct username");
+ }
+ return null;
+ }
+ else
+ {
+ if (dn.contains("DC="))
+ {
+ int start = 0;
+ String dc = "";
+
+ while (dn.indexOf("DC=", start) != -1)
+ {
+ int dcStart = dn.indexOf("DC=", start) + 3;
+ int dcEnd = (dn.indexOf(",", dn.indexOf("DC=", start)) != -1) ? dn.indexOf(",", dn.indexOf("DC=", start)) : dn.length();
+
+ if (dc.isEmpty())
+ {
+ dc = dn.substring(dcStart, dcEnd);
+ }
+ else
+ {
+ dc = dc.concat(".").concat(dn.substring(dcStart, dcEnd));
+ }
+
+ start = dn.indexOf("DC=", start) + 1;
+ }
+
+ username = username.concat("@").concat(dc);
+ }
+ }
+
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Constructing Principal with username: " + username);
+ }
+ return new UsernamePrincipal(username);
+ }
+ else
+ {
+ // No CN => Cannot construct username => Authentication failed => return null
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("No CN= present in DN, unable to construct username");
+ }
+ return null;
+ }
+ }
+ else
+ {
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Using external Principal: " + _externalPrincipal);
+ }
+
+ return _externalPrincipal;
+ }
}
} \ No newline at end of file