git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@769838 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Bosanac Dejan 2009-04-29 17:14:15 +00:00
parent d62860f98c
commit 6999a02d70
11 changed files with 262 additions and 660 deletions

View File

@ -36,86 +36,76 @@
<build> <build>
<plugins> <plugins>
<!-- Configure which tests are included/excuded --> <!-- Configure which tests are included/excuded -->
<plugin> <plugin>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<configuration> <configuration>
<childDelegation>true</childDelegation> <forkMode>pertest</forkMode>
<forkMode>once</forkMode> <childDelegation>false</childDelegation>
<excludes> <useFile>true</useFile>
<exclude implementation="java.lang.String">**/LDAPLoginModuleTest.*</exclude> <argLine>-Xmx512M</argLine>
</excludes>
<includes> <systemProperties>
<include implementation="java.lang.String">**/*Test.*</include> <property>
</includes> <name>org.apache.activemq.default.directory.prefix</name>
<value>target/</value>
</property>
<property>
<name>log4j.configuration</name>
<value>file:target/test-classes/log4j.properties</value>
</property>
</systemProperties>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId> <artifactId>commons-logging</artifactId>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>directory</groupId> <groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-core</artifactId> <artifactId>apacheds-core-integ</artifactId>
<version>${directory-version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>directory</groupId> <groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-shared</artifactId> <artifactId>apacheds-server-integ</artifactId>
<version>${directory-version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>directory-shared</groupId>
<artifactId>apache-ldapber-provider</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>directory-shared</groupId>
<artifactId>ldap-common</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>directory-asn1</groupId>
<artifactId>asn1-codec</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>directory-asn1</groupId>
<artifactId>asn1-der</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>directory-shared</groupId>
<artifactId>kerberos-common</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>directory-network</groupId>
<artifactId>mina</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>directory-protocols</groupId>
<artifactId>kerberos-protocol</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>directory-protocols</groupId>
<artifactId>ldap-protocol</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<optional>true</optional>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>nlog4j</artifactId>
<version>${nlog4j-version}</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -77,48 +77,35 @@ public class LDAPLoginModule implements LoginModule {
protected DirContext context; protected DirContext context;
private Subject subject; private Subject subject;
private CallbackHandler handler; private CallbackHandler handler;
private String initialContextFactory; private LDAPLoginProperty [] config;
private String connectionURL;
private String connectionUsername;
private String connectionPassword;
private String connectionProtocol;
private String authentication;
private String userBase;
private String roleBase;
private String roleName;
private String userRoleName;
private String username; private String username;
private MessageFormat userSearchMatchingFormat;
private MessageFormat roleSearchMatchingFormat;
private boolean userSearchSubtreeBool;
private boolean roleSearchSubtreeBool;
private Set<GroupPrincipal> groups = new HashSet<GroupPrincipal>(); private Set<GroupPrincipal> groups = new HashSet<GroupPrincipal>();
public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
this.subject = subject; this.subject = subject;
this.handler = callbackHandler; this.handler = callbackHandler;
initialContextFactory = (String)options.get(INITIAL_CONTEXT_FACTORY);
connectionURL = (String)options.get(CONNECTION_URL); config = new LDAPLoginProperty [] {
connectionUsername = (String)options.get(CONNECTION_USERNAME); new LDAPLoginProperty (INITIAL_CONTEXT_FACTORY, (String)options.get(INITIAL_CONTEXT_FACTORY)),
connectionPassword = (String)options.get(CONNECTION_PASSWORD); new LDAPLoginProperty (CONNECTION_URL, (String)options.get(CONNECTION_URL)),
connectionProtocol = (String)options.get(CONNECTION_PROTOCOL); new LDAPLoginProperty (CONNECTION_USERNAME, (String)options.get(CONNECTION_USERNAME)),
authentication = (String)options.get(AUTHENTICATION); new LDAPLoginProperty (CONNECTION_PASSWORD, (String)options.get(CONNECTION_PASSWORD)),
userBase = (String)options.get(USER_BASE); new LDAPLoginProperty (CONNECTION_PROTOCOL, (String)options.get(CONNECTION_PROTOCOL)),
String userSearchMatching = (String)options.get(USER_SEARCH_MATCHING); new LDAPLoginProperty (AUTHENTICATION, (String)options.get(AUTHENTICATION)),
String userSearchSubtree = (String)options.get(USER_SEARCH_SUBTREE); new LDAPLoginProperty (USER_BASE, (String)options.get(USER_BASE)),
roleBase = (String)options.get(ROLE_BASE); new LDAPLoginProperty (USER_SEARCH_MATCHING, (String)options.get(USER_SEARCH_MATCHING)),
roleName = (String)options.get(ROLE_NAME); new LDAPLoginProperty (USER_SEARCH_SUBTREE, (String)options.get(USER_SEARCH_SUBTREE)),
String roleSearchMatching = (String)options.get(ROLE_SEARCH_MATCHING); new LDAPLoginProperty (ROLE_BASE, (String)options.get(ROLE_BASE)),
String roleSearchSubtree = (String)options.get(ROLE_SEARCH_SUBTREE); new LDAPLoginProperty (ROLE_NAME, (String)options.get(ROLE_NAME)),
userRoleName = (String)options.get(USER_ROLE_NAME); new LDAPLoginProperty (ROLE_SEARCH_MATCHING, (String)options.get(ROLE_SEARCH_MATCHING)),
userSearchMatchingFormat = new MessageFormat(userSearchMatching); new LDAPLoginProperty (ROLE_SEARCH_SUBTREE, (String)options.get(ROLE_SEARCH_SUBTREE)),
roleSearchMatchingFormat = new MessageFormat(roleSearchMatching); new LDAPLoginProperty (USER_ROLE_NAME, (String)options.get(USER_ROLE_NAME)),
userSearchSubtreeBool = Boolean.valueOf(userSearchSubtree).booleanValue(); };
roleSearchSubtreeBool = Boolean.valueOf(roleSearchSubtree).booleanValue();
} }
public boolean login() throws LoginException { public boolean login() throws LoginException {
Callback[] callbacks = new Callback[2]; Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("User name"); callbacks[0] = new NameCallback("User name");
@ -130,12 +117,17 @@ public class LDAPLoginModule implements LoginModule {
} catch (UnsupportedCallbackException uce) { } catch (UnsupportedCallbackException uce) {
throw (LoginException)new LoginException().initCause(uce); throw (LoginException)new LoginException().initCause(uce);
} }
String password;
username = ((NameCallback)callbacks[0]).getName(); username = ((NameCallback)callbacks[0]).getName();
String password = new String(((PasswordCallback)callbacks[1]).getPassword()); if (username == null)
return false;
if (username == null || "".equals(username) || password == null || "".equals(password)) {
return false; if (((PasswordCallback)callbacks[1]).getPassword() != null)
} password = new String(((PasswordCallback)callbacks[1]).getPassword());
else
password="";
try { try {
boolean result = authenticate(username, password); boolean result = authenticate(username, password);
@ -179,8 +171,17 @@ public class LDAPLoginModule implements LoginModule {
protected boolean authenticate(String username, String password) throws Exception { protected boolean authenticate(String username, String password) throws Exception {
MessageFormat userSearchMatchingFormat;
boolean userSearchSubtreeBool;
DirContext context = null; DirContext context = null;
context = open(); context = open();
if (!isLoginPropertySet(USER_SEARCH_MATCHING))
return false;
userSearchMatchingFormat = new MessageFormat(getLDAPPropertyValue(USER_SEARCH_MATCHING));
userSearchSubtreeBool = Boolean.valueOf(getLDAPPropertyValue(USER_SEARCH_SUBTREE)).booleanValue();
try { try {
@ -196,14 +197,14 @@ public class LDAPLoginModule implements LoginModule {
// setup attributes // setup attributes
ArrayList<String> list = new ArrayList<String>(); ArrayList<String> list = new ArrayList<String>();
if (userRoleName != null) { if (isLoginPropertySet(USER_ROLE_NAME)) {
list.add(userRoleName); list.add(getLDAPPropertyValue(USER_ROLE_NAME));
} }
String[] attribs = new String[list.size()]; String[] attribs = new String[list.size()];
list.toArray(attribs); list.toArray(attribs);
constraints.setReturningAttributes(attribs); constraints.setReturningAttributes(attribs);
NamingEnumeration results = context.search(userBase, filter, constraints); NamingEnumeration results = context.search(getLDAPPropertyValue(USER_BASE), filter, constraints);
if (results == null || !results.hasMore()) { if (results == null || !results.hasMore()) {
return false; return false;
@ -216,7 +217,7 @@ public class LDAPLoginModule implements LoginModule {
} }
NameParser parser = context.getNameParser(""); NameParser parser = context.getNameParser("");
Name contextName = parser.parse(context.getNameInNamespace()); Name contextName = parser.parse(context.getNameInNamespace());
Name baseName = parser.parse(userBase); Name baseName = parser.parse(getLDAPPropertyValue(USER_BASE));
Name entryName = parser.parse(result.getName()); Name entryName = parser.parse(result.getName());
Name name = contextName.addAll(baseName); Name name = contextName.addAll(baseName);
name = name.addAll(entryName); name = name.addAll(entryName);
@ -227,8 +228,8 @@ public class LDAPLoginModule implements LoginModule {
return false; return false;
} }
ArrayList<String> roles = null; ArrayList<String> roles = null;
if (userRoleName != null) { if (isLoginPropertySet(USER_ROLE_NAME)) {
roles = addAttributeValues(userRoleName, attrs, roles); roles = addAttributeValues(getLDAPPropertyValue(USER_ROLE_NAME), attrs, roles);
} }
// check the credentials by binding to server // check the credentials by binding to server
@ -255,10 +256,15 @@ public class LDAPLoginModule implements LoginModule {
protected ArrayList<String> getRoles(DirContext context, String dn, String username, ArrayList<String> currentRoles) throws NamingException { protected ArrayList<String> getRoles(DirContext context, String dn, String username, ArrayList<String> currentRoles) throws NamingException {
ArrayList<String> list = currentRoles; ArrayList<String> list = currentRoles;
MessageFormat roleSearchMatchingFormat;
boolean roleSearchSubtreeBool;
roleSearchMatchingFormat = new MessageFormat(getLDAPPropertyValue(ROLE_SEARCH_MATCHING));
roleSearchSubtreeBool = Boolean.valueOf(getLDAPPropertyValue(ROLE_SEARCH_SUBTREE)).booleanValue();
if (list == null) { if (list == null) {
list = new ArrayList<String>(); list = new ArrayList<String>();
} }
if (roleName == null || "".equals(roleName)) { if (!isLoginPropertySet(ROLE_NAME)) {
return list; return list;
} }
String filter = roleSearchMatchingFormat.format(new String[] { String filter = roleSearchMatchingFormat.format(new String[] {
@ -271,14 +277,14 @@ public class LDAPLoginModule implements LoginModule {
} else { } else {
constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE); constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE);
} }
NamingEnumeration results = context.search(roleBase, filter, constraints); NamingEnumeration results = context.search(getLDAPPropertyValue(ROLE_BASE), filter, constraints);
while (results.hasMore()) { while (results.hasMore()) {
SearchResult result = (SearchResult)results.next(); SearchResult result = (SearchResult)results.next();
Attributes attrs = result.getAttributes(); Attributes attrs = result.getAttributes();
if (attrs == null) { if (attrs == null) {
continue; continue;
} }
list = addAttributeValues(roleName, attrs, list); list = addAttributeValues(getLDAPPropertyValue(ROLE_NAME), attrs, list);
} }
return list; return list;
@ -325,14 +331,14 @@ public class LDAPLoginModule implements LoginModule {
log.debug("Authentication failed for dn=" + dn); log.debug("Authentication failed for dn=" + dn);
} }
if (connectionUsername != null) { if (isLoginPropertySet(CONNECTION_USERNAME)) {
context.addToEnvironment(Context.SECURITY_PRINCIPAL, connectionUsername); context.addToEnvironment(Context.SECURITY_PRINCIPAL, getLDAPPropertyValue(CONNECTION_USERNAME));
} else { } else {
context.removeFromEnvironment(Context.SECURITY_PRINCIPAL); context.removeFromEnvironment(Context.SECURITY_PRINCIPAL);
} }
if (connectionPassword != null) { if (isLoginPropertySet(CONNECTION_PASSWORD)) {
context.addToEnvironment(Context.SECURITY_CREDENTIALS, connectionPassword); context.addToEnvironment(Context.SECURITY_CREDENTIALS, getLDAPPropertyValue(CONNECTION_PASSWORD));
} else { } else {
context.removeFromEnvironment(Context.SECURITY_CREDENTIALS); context.removeFromEnvironment(Context.SECURITY_CREDENTIALS);
} }
@ -361,22 +367,18 @@ public class LDAPLoginModule implements LoginModule {
} }
protected DirContext open() throws NamingException { protected DirContext open() throws NamingException {
if (context != null) {
return context;
}
try { try {
Hashtable<String, String> env = new Hashtable<String, String>(); Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory); env.put(Context.INITIAL_CONTEXT_FACTORY, getLDAPPropertyValue(INITIAL_CONTEXT_FACTORY));
if (connectionUsername != null || !"".equals(connectionUsername)) { if (isLoginPropertySet(CONNECTION_USERNAME)) {
env.put(Context.SECURITY_PRINCIPAL, connectionUsername); env.put(Context.SECURITY_PRINCIPAL, getLDAPPropertyValue(CONNECTION_USERNAME));
} }
if (connectionPassword != null || !"".equals(connectionPassword)) { if (isLoginPropertySet(CONNECTION_PASSWORD)) {
env.put(Context.SECURITY_CREDENTIALS, connectionPassword); env.put(Context.SECURITY_CREDENTIALS, getLDAPPropertyValue(CONNECTION_PASSWORD));
} }
env.put(Context.SECURITY_PROTOCOL, connectionProtocol); env.put(Context.SECURITY_PROTOCOL, getLDAPPropertyValue(CONNECTION_PROTOCOL));
env.put(Context.PROVIDER_URL, connectionURL); env.put(Context.PROVIDER_URL, getLDAPPropertyValue(CONNECTION_URL));
env.put(Context.SECURITY_AUTHENTICATION, authentication); env.put(Context.SECURITY_AUTHENTICATION, getLDAPPropertyValue(AUTHENTICATION));
context = new InitialDirContext(env); context = new InitialDirContext(env);
} catch (NamingException e) { } catch (NamingException e) {
@ -385,5 +387,20 @@ public class LDAPLoginModule implements LoginModule {
} }
return context; return context;
} }
private String getLDAPPropertyValue (String propertyName){
for (int i=0; i < config.length; i++ )
if (config[i].getPropertyName() == propertyName)
return config[i].getPropertyValue();
return null;
}
private boolean isLoginPropertySet(String propertyName) {
for (int i=0; i < config.length; i++ ) {
if (config[i].getPropertyName() == propertyName && config[i].getPropertyValue() != null)
return true;
}
return false;
}
} }

View File

@ -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.activemq.jaas;
public class LDAPLoginProperty {
private String name;
private String value;
public LDAPLoginProperty(String name) {
this.name = name;
}
public LDAPLoginProperty(String name, String value) {
this.name = name;
this.value = value;
}
public String getPropertyName() {
return this.name;
}
public String getPropertyValue() {
return this.value;
}
}

View File

@ -16,12 +16,13 @@
*/ */
package org.apache.activemq.jaas; package org.apache.activemq.jaas;
import java.io.File; import static org.junit.Assert.assertTrue;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.URL;
import java.util.HashSet; import java.util.HashSet;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Properties;
import javax.naming.Context; import javax.naming.Context;
import javax.naming.NameClassPair; import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration; import javax.naming.NamingEnumeration;
@ -35,40 +36,60 @@ import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException; import javax.security.auth.login.LoginException;
import junit.framework.TestCase; import org.apache.directory.server.core.integ.Level;
import org.apache.directory.server.core.integ.annotations.ApplyLdifs;
import org.apache.activemq.jaas.ldap.MutableServerStartupConfiguration; import org.apache.directory.server.core.integ.annotations.CleanupLevel;
import org.apache.activemq.jaas.ldap.ServerContextFactory; import org.apache.directory.server.integ.SiRunner;
import org.apache.ldap.server.configuration.ShutdownConfiguration; import org.apache.directory.server.ldap.LdapService;
import org.apache.ldap.server.jndi.CoreContextFactory; import org.junit.Test;
import org.junit.runner.RunWith;
/**
* @version $Rev: $ $Date: $
*/
public class LDAPLoginModuleTest extends TestCase {
@RunWith ( SiRunner.class )
@CleanupLevel ( Level.CLASS )
@ApplyLdifs( {
"dn: uid=first,ou=system\n" +
"uid: first\n" +
"userPassword: secret\n" +
"objectClass: account\n" +
"objectClass: simpleSecurityObject\n" +
"objectClass: top\n"
}
)
public class LDAPLoginModuleTest {
static {
String path = System.getProperty("java.security.auth.login.config");
if (path == null) {
URL resource = PropertiesLoginModuleTest.class.getClassLoader().getResource("login.config");
if (resource != null) {
path = resource.getFile();
System.setProperty("java.security.auth.login.config", path);
}
}
}
private static final String BASE = "ou=system";
public static LdapService ldapService;
private static final String FILTER = "(objectclass=*)";
private static final String PRINCIPAL = "uid=admin,ou=system"; private static final String PRINCIPAL = "uid=admin,ou=system";
private static final String CREDENTIALS = "secret"; private static final String CREDENTIALS = "secret";
public void testNothing() {
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Test
public void testRunning() throws Exception { public void testRunning() throws Exception {
Hashtable env = new Hashtable(); Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL, "ldap://localhost:9389"); env.put(Context.PROVIDER_URL, "ldap://localhost:1024");
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, PRINCIPAL); env.put(Context.SECURITY_PRINCIPAL, PRINCIPAL);
env.put(Context.SECURITY_CREDENTIALS, CREDENTIALS); env.put(Context.SECURITY_CREDENTIALS, CREDENTIALS);
DirContext ctx = new InitialDirContext(env); DirContext ctx = new InitialDirContext(env);
// Perform search using URL
// NamingEnumeration answer = ctx.search(
// "ldap://localhost:389/ou=system", "(uid=admin)", null);
HashSet set = new HashSet(); HashSet set = new HashSet();
NamingEnumeration list = ctx.list("ou=system"); NamingEnumeration list = ctx.list("ou=system");
@ -85,8 +106,9 @@ public class LDAPLoginModuleTest extends TestCase {
assertTrue(set.contains("prefNodeName=sysPrefRoot")); assertTrue(set.contains("prefNodeName=sysPrefRoot"));
} }
public void xtestLogin() throws LoginException { @Test
public void testLogin() throws LoginException {
LoginContext context = new LoginContext("LDAPLogin", new CallbackHandler() { LoginContext context = new LoginContext("LDAPLogin", new CallbackHandler() {
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) { for (int i = 0; i < callbacks.length; i++) {
@ -104,39 +126,4 @@ public class LDAPLoginModuleTest extends TestCase {
context.logout(); context.logout();
} }
@SuppressWarnings("unchecked")
public void setUp() throws Exception {
MutableServerStartupConfiguration startup = new MutableServerStartupConfiguration();
// put some mandatory JNDI properties here
startup.setWorkingDirectory(new File("target/ldap"));
startup.setAllowAnonymousAccess(true);
startup.setLdapPort(9389);
startup.setEnableNetworking(true);
startup.setHost(InetAddress.getByName("localhost"));
Properties env = new Properties();
env.putAll(startup.toJndiEnvironment());
env.put(Context.INITIAL_CONTEXT_FACTORY, ServerContextFactory.class.getName());
env.put(Context.PROVIDER_URL, "ou=system");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, PRINCIPAL);
env.put(Context.SECURITY_CREDENTIALS, CREDENTIALS);
//Fire it up
new InitialDirContext(env);
}
@SuppressWarnings("unchecked")
public void tearDown() throws Exception {
Properties env = new Properties();
env.putAll(new ShutdownConfiguration().toJndiEnvironment());
env.put(Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName());
env.put(Context.PROVIDER_URL, "ou=system");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, PRINCIPAL);
env.put(Context.SECURITY_CREDENTIALS, CREDENTIALS);
//Shut it down
new InitialDirContext(env);
}
} }

View File

@ -46,7 +46,6 @@ public class PropertiesLoginModuleTest extends TestCase {
System.setProperty("java.security.auth.login.config", path); System.setProperty("java.security.auth.login.config", path);
} }
} }
System.out.println("Path to login config: " + path);
} }
public void testLogin() throws LoginException { public void testLogin() throws LoginException {

View File

@ -1,85 +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.activemq.jaas.ldap;
import java.io.File;
import java.net.InetAddress;
import java.util.List;
import java.util.Set;
import org.apache.mina.registry.ServiceRegistry;
/**
* A mutable version of {@link ServerStartupConfiguration}.
*
* @version $Rev: 233391 $ $Date: 2005-08-18 16:38:47 -0600 (Thu, 18 Aug 2005) $
*/
public class MutableServerStartupConfiguration extends ServerStartupConfiguration {
private static final long serialVersionUID = 515104910980600099L;
public MutableServerStartupConfiguration() {
super();
}
public void setAllowAnonymousAccess(boolean arg0) {
super.setAllowAnonymousAccess(arg0);
}
public void setAuthenticatorConfigurations(Set arg0) {
super.setAuthenticatorConfigurations(arg0);
}
public void setBootstrapSchemas(Set arg0) {
super.setBootstrapSchemas(arg0);
}
public void setContextPartitionConfigurations(Set arg0) {
super.setContextPartitionConfigurations(arg0);
}
public void setInterceptorConfigurations(List arg0) {
super.setInterceptorConfigurations(arg0);
}
public void setTestEntries(List arg0) {
super.setTestEntries(arg0);
}
public void setWorkingDirectory(File arg0) {
super.setWorkingDirectory(arg0);
}
public void setEnableKerberos(boolean enableKerberos) {
super.setEnableKerberos(enableKerberos);
}
public void setHost(InetAddress host) {
super.setHost(host);
}
public void setLdapPort(int ldapPort) {
super.setLdapPort(ldapPort);
}
public void setLdapsPort(int ldapsPort) {
super.setLdapsPort(ldapsPort);
}
public void setMinaServiceRegistry(ServiceRegistry minaServiceRegistry) {
super.setMinaServiceRegistry(minaServiceRegistry);
}
}

View File

@ -1,199 +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.activemq.jaas.ldap;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.ldap.Control;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.kerberos.protocol.KerberosProtocolProvider;
import org.apache.kerberos.sam.SamSubsystem;
import org.apache.kerberos.service.KdcConfiguration;
import org.apache.kerberos.store.JndiPrincipalStoreImpl;
import org.apache.kerberos.store.PrincipalStore;
import org.apache.ldap.common.exception.LdapConfigurationException;
import org.apache.ldap.common.name.LdapName;
import org.apache.ldap.common.util.NamespaceTools;
import org.apache.ldap.common.util.PropertiesUtils;
import org.apache.ldap.server.jndi.ContextFactoryService;
import org.apache.ldap.server.jndi.CoreContextFactory;
import org.apache.ldap.server.protocol.LdapProtocolProvider;
import org.apache.mina.common.TransportType;
import org.apache.mina.registry.Service;
import org.apache.mina.registry.ServiceRegistry;
/**
* Adds additional bootstrapping for server socket listeners when firing up the
* server.
*
* @version $Rev: 233391 $ $Date: 2005-08-18 16:38:47 -0600 (Thu, 18 Aug 2005) $
* @see javax.naming.spi.InitialContextFactory
*/
public class ServerContextFactory extends CoreContextFactory {
private static final Log LOG = LogFactory.getLog(ServerContextFactory.class);
private static Service ldapService;
private static Service kerberosService;
private static ServiceRegistry minaRegistry;
protected ServiceRegistry getMinaRegistry() {
return minaRegistry;
}
public void afterShutdown(ContextFactoryService service) {
if (minaRegistry != null) {
if (ldapService != null) {
minaRegistry.unbind(ldapService);
if (LOG.isInfoEnabled()) {
LOG.info("Unbind of LDAP Service complete: " + ldapService);
}
ldapService = null;
}
if (kerberosService != null) {
minaRegistry.unbind(kerberosService);
if (LOG.isInfoEnabled()) {
LOG.info("Unbind of KRB5 Service complete: " + kerberosService);
}
kerberosService = null;
}
}
}
public void afterStartup(ContextFactoryService service) throws NamingException {
ServerStartupConfiguration cfg = (ServerStartupConfiguration)service.getConfiguration().getStartupConfiguration();
Hashtable env = service.getConfiguration().getEnvironment();
if (cfg.isEnableNetworking()) {
setupRegistry(cfg);
startLdapProtocol(cfg, env);
if (cfg.isEnableKerberos()) {
startKerberosProtocol(env);
}
}
}
/**
* Starts up the MINA registry so various protocol providers can be started.
*/
private void setupRegistry(ServerStartupConfiguration cfg) {
minaRegistry = cfg.getMinaServiceRegistry();
}
/**
* Starts the Kerberos protocol provider which is backed by the LDAP store.
*
* @throws NamingException if there are problems starting up the Kerberos
* provider
*/
private void startKerberosProtocol(Hashtable env) throws NamingException {
/*
* Looks like KdcConfiguration takes properties and we use Hashtable for
* JNDI so I'm copying over the String based properties into a new
* Properties obj.
*/
Properties props = new Properties();
Iterator list = env.keySet().iterator();
while (list.hasNext()) {
String key = (String)list.next();
if (env.get(key) instanceof String) {
props.setProperty(key, (String)env.get(key));
}
}
// construct the configuration, get the port, create the service, and
// prepare kdc objects
KdcConfiguration config = new KdcConfiguration(props);
int port = PropertiesUtils.get(env, KdcConfiguration.KERBEROS_PORT_KEY, KdcConfiguration.DEFAULT_KERBEROS_PORT);
Service service = new Service("kerberos", TransportType.DATAGRAM, new InetSocketAddress(port));
LdapContext ctx = getBaseRealmContext(config, env);
PrincipalStore store = new JndiPrincipalStoreImpl(ctx, new LdapName("ou=Users"));
SamSubsystem.getInstance().setUserContext((DirContext)ctx, "ou=Users");
try {
minaRegistry.bind(service, new KerberosProtocolProvider(config, store));
kerberosService = service;
if (LOG.isInfoEnabled()) {
LOG.info("Successful bind of KRB5 Service completed: " + kerberosService);
}
} catch (IOException e) {
LOG.error("Could not start the kerberos service on port " + KdcConfiguration.DEFAULT_KERBEROS_PORT, e);
}
}
/**
* Maps a Kerberos Realm name to a position within the DIT. The primary
* realm of the KDC will use this area for configuration and for storing
* user entries.
*
* @param config the KDC's configuration
* @param env the JNDI environment properties
* @return the base context for the primary realm of the KDC
* @throws NamingException
*/
@SuppressWarnings("unchecked")
private LdapContext getBaseRealmContext(KdcConfiguration config, Hashtable env) throws NamingException {
Hashtable cloned = (Hashtable)env.clone();
String dn = NamespaceTools.inferLdapName(config.getPrimaryRealm());
cloned.put(Context.PROVIDER_URL, dn);
if (LOG.isInfoEnabled()) {
LOG.info("Getting initial context for realm base at " + dn + " for " + config.getPrimaryRealm());
}
return new InitialLdapContext(cloned, new Control[] {});
}
/**
* Starts up the LDAP protocol provider to service LDAP requests
*
* @throws NamingException if there are problems starting the LDAP provider
*/
private void startLdapProtocol(ServerStartupConfiguration cfg, Hashtable env) throws NamingException {
int port = cfg.getLdapPort();
InetAddress host = cfg.getHost();
Service service = new Service("ldap", TransportType.SOCKET, new InetSocketAddress(host, port));
try {
minaRegistry.bind(service, new LdapProtocolProvider((Hashtable)env.clone()));
ldapService = service;
if (LOG.isInfoEnabled()) {
LOG.info("Successful bind of LDAP Service completed: " + ldapService);
}
} catch (IOException e) {
String msg = "Failed to bind the LDAP protocol service to the service registry: " + service;
LdapConfigurationException lce = new LdapConfigurationException(msg);
lce.setRootCause(e);
LOG.error(msg, e);
throw lce;
}
}
}

View File

@ -1,126 +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.activemq.jaas.ldap;
import java.net.InetAddress;
import org.apache.ldap.server.configuration.ConfigurationException;
import org.apache.ldap.server.configuration.StartupConfiguration;
import org.apache.mina.registry.ServiceRegistry;
import org.apache.mina.registry.SimpleServiceRegistry;
/**
* A {@link StartupConfiguration} that starts up ApacheDS with network layer support.
*
* @version $Rev: 233391 $ $Date: 2005-08-18 16:38:47 -0600 (Thu, 18 Aug 2005) $
*/
public class ServerStartupConfiguration extends StartupConfiguration {
private static final long serialVersionUID = -7138616822614155454L;
private boolean enableNetworking = true;
private ServiceRegistry minaServiceRegistry = new SimpleServiceRegistry();
private int ldapPort = 389;
private int ldapsPort = 636;
private InetAddress host;
private boolean enableKerberos;
protected ServerStartupConfiguration() {
}
protected InetAddress getHost() {
return host;
}
protected void setHost(InetAddress host) {
this.host = host;
}
/**
* Returns <tt>true</tt> if networking (LDAP, LDAPS, and Kerberos) is enabled.
*/
public boolean isEnableNetworking() {
return enableNetworking;
}
/**
* Sets whether to enable networking (LDAP, LDAPS, and Kerberos) or not.
*/
public void setEnableNetworking(boolean enableNetworking) {
this.enableNetworking = enableNetworking;
}
/**
* Returns <tt>true</tt> if Kerberos support is enabled.
*/
public boolean isEnableKerberos() {
return enableKerberos;
}
/**
* Sets whether to enable Kerberos support or not.
*/
protected void setEnableKerberos(boolean enableKerberos) {
this.enableKerberos = enableKerberos;
}
/**
* Returns LDAP TCP/IP port number to listen to.
*/
public int getLdapPort() {
return ldapPort;
}
/**
* Sets LDAP TCP/IP port number to listen to.
*/
protected void setLdapPort(int ldapPort) {
this.ldapPort = ldapPort;
}
/**
* Returns LDAPS TCP/IP port number to listen to.
*/
public int getLdapsPort() {
return ldapsPort;
}
/**
* Sets LDAPS TCP/IP port number to listen to.
*/
protected void setLdapsPort(int ldapsPort) {
this.ldapsPort = ldapsPort;
}
/**
* Returns <a href="http://directory.apache.org/subprojects/network/">MINA</a>
* {@link ServiceRegistry} that will be used by ApacheDS.
*/
public ServiceRegistry getMinaServiceRegistry() {
return minaServiceRegistry;
}
/**
* Sets <a href="http://directory.apache.org/subprojects/network/">MINA</a>
* {@link ServiceRegistry} that will be used by ApacheDS.
*/
protected void setMinaServiceRegistry(ServiceRegistry minaServiceRegistry) {
if (minaServiceRegistry == null) {
throw new ConfigurationException("MinaServiceRegistry cannot be null");
}
this.minaServiceRegistry = minaServiceRegistry;
}
}

View File

@ -0,0 +1,35 @@
## ---------------------------------------------------------------------------
## 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.
## ---------------------------------------------------------------------------
#
# The logging properties used during tests..
#
log4j.rootLogger=INFO, out, stdout
log4j.logger.org.apache.activemq=INFO
# CONSOLE appender not used by default
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
# File appender
log4j.appender.out=org.apache.log4j.FileAppender
log4j.appender.out.layout=org.apache.log4j.PatternLayout
log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
log4j.appender.out.file=target/activemq-test.log
log4j.appender.out.append=true

View File

@ -12,7 +12,7 @@
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
PropertiesLogin { PropertiesLogin {
org.apache.activemq.jaas.PropertiesLoginModule required org.apache.activemq.jaas.PropertiesLoginModule required
@ -25,11 +25,18 @@ LDAPLogin {
org.apache.activemq.jaas.LDAPLoginModule required org.apache.activemq.jaas.LDAPLoginModule required
debug=true debug=true
initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
connectionURL="ldap://localhost:9389" connectionURL="ldap://localhost:1024"
connectionUsername="uid=admin,ou=system" connectionUsername="uid=admin,ou=system"
connectionPassword=secret connectionPassword=secret
connectionProtocol=s connectionProtocol=s
authentication=simple authentication=simple
userBase="ou=system"
userSearchMatching="(uid={0})"
userSearchSubtree=false
roleBase="ou=system"
roleName=dummyRoleName
roleSearchMatching="(uid={1})"
roleSearchSubtree=false
; ;
}; };

73
pom.xml
View File

@ -45,7 +45,7 @@
<camel-version>2.0-SNAPSHOT</camel-version> <camel-version>2.0-SNAPSHOT</camel-version>
<cglib-version>2.0</cglib-version> <cglib-version>2.0</cglib-version>
<commons-beanutils-version>1.6.1</commons-beanutils-version> <commons-beanutils-version>1.6.1</commons-beanutils-version>
<commons-collections-version>3.1</commons-collections-version> <commons-collections-version>3.2.1</commons-collections-version>
<openjpa-version>1.2.0</openjpa-version> <openjpa-version>1.2.0</openjpa-version>
<commons-dbcp-version>1.2.2</commons-dbcp-version> <commons-dbcp-version>1.2.2</commons-dbcp-version>
<commons-httpclient-version>2.0.1</commons-httpclient-version> <commons-httpclient-version>2.0.1</commons-httpclient-version>
@ -55,18 +55,19 @@
<directory-asn1-version>0.3.2</directory-asn1-version> <directory-asn1-version>0.3.2</directory-asn1-version>
<directory-kerboros-version>0.5</directory-kerboros-version> <directory-kerboros-version>0.5</directory-kerboros-version>
<directory-mina-version>0.7.3</directory-mina-version> <directory-mina-version>0.7.3</directory-mina-version>
<directory-version>0.9.2</directory-version> <directory-version>1.5.4</directory-version>
<geronimo-version>1.0</geronimo-version> <geronimo-version>1.0</geronimo-version>
<howl-version>0.1.8</howl-version> <howl-version>0.1.8</howl-version>
<hsqldb-version>1.7.2.2</hsqldb-version> <hsqldb-version>1.7.2.2</hsqldb-version>
<jdom-version>1.0</jdom-version> <jdom-version>1.0</jdom-version>
<jetty-version>6.1.9</jetty-version> <jetty-version>6.1.9</jetty-version>
<jmock-version>1.0.1</jmock-version> <jmock-version>1.0.1</jmock-version>
<junit-version>3.8.1</junit-version> <junit-version>4.4</junit-version>
<jxta-version>2.0</jxta-version> <jxta-version>2.0</jxta-version>
<log4j-version>1.2.14</log4j-version> <log4j-version>1.2.14</log4j-version>
<nlog4j-version>1.2.25</nlog4j-version>
<org-apache-derby-version>10.1.3.1</org-apache-derby-version> <org-apache-derby-version>10.1.3.1</org-apache-derby-version>
<org-apache-maven-surefire-plugin-version>2.2</org-apache-maven-surefire-plugin-version> <org-apache-maven-surefire-plugin-version>2.3</org-apache-maven-surefire-plugin-version>
<p2psockets-version>1.1.2</p2psockets-version> <p2psockets-version>1.1.2</p2psockets-version>
<regexp-version>1.3</regexp-version> <regexp-version>1.3</regexp-version>
<rome-version>0.8</rome-version> <rome-version>0.8</rome-version>
@ -853,70 +854,6 @@
<version>${jdom-version}</version> <version>${jdom-version}</version>
</dependency> </dependency>
<!-- ACTIVEMQ-JAAS Dependencies -->
<dependency>
<groupId>directory</groupId>
<artifactId>apacheds-core</artifactId>
<version>${directory-version}</version>
</dependency>
<dependency>
<groupId>directory</groupId>
<artifactId>apacheds-shared</artifactId>
<version>${directory-version}</version>
</dependency>
<dependency>
<groupId>directory-shared</groupId>
<artifactId>apache-ldapber-provider</artifactId>
<version>${directory-version}</version>
<exclusions>
<exclusion>
<groupId>commons-test</groupId>
<artifactId>commons-test</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>directory-shared</groupId>
<artifactId>ldap-common</artifactId>
<version>${directory-version}</version>
</dependency>
<dependency>
<groupId>directory-asn1</groupId>
<artifactId>asn1-codec</artifactId>
<version>${directory-asn1-version}</version>
</dependency>
<dependency>
<groupId>directory-asn1</groupId>
<artifactId>asn1-der</artifactId>
<version>${directory-asn1-version}</version>
<exclusions>
<exclusion>
<groupId>commons-test</groupId>
<artifactId>commons-test</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>directory-shared</groupId>
<artifactId>kerberos-common</artifactId>
<version>${directory-kerboros-version}</version>
</dependency>
<dependency>
<groupId>directory-network</groupId>
<artifactId>mina</artifactId>
<version>${directory-mina-version}</version>
</dependency>
<dependency>
<groupId>directory-protocols</groupId>
<artifactId>kerberos-protocol</artifactId>
<version>${directory-kerboros-version}</version>
</dependency>
<dependency>
<groupId>directory-protocols</groupId>
<artifactId>ldap-protocol</artifactId>
<version>${directory-version}</version>
</dependency>
<dependency> <dependency>
<groupId>p2psockets</groupId> <groupId>p2psockets</groupId>
<artifactId>p2psockets-core</artifactId> <artifactId>p2psockets-core</artifactId>