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>
<plugins>
<!-- Configure which tests are included/excuded -->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<childDelegation>true</childDelegation>
<forkMode>once</forkMode>
<excludes>
<exclude implementation="java.lang.String">**/LDAPLoginModuleTest.*</exclude>
</excludes>
<includes>
<include implementation="java.lang.String">**/*Test.*</include>
</includes>
<forkMode>pertest</forkMode>
<childDelegation>false</childDelegation>
<useFile>true</useFile>
<argLine>-Xmx512M</argLine>
<systemProperties>
<property>
<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>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>directory</groupId>
<artifactId>apacheds-core</artifactId>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-core-integ</artifactId>
<version>${directory-version}</version>
<scope>test</scope>
</dependency>
</dependency>
<dependency>
<groupId>directory</groupId>
<artifactId>apacheds-shared</artifactId>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-server-integ</artifactId>
<version>${directory-version}</version>
<scope>test</scope>
</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>
<artifactId>junit</artifactId>
<scope>test</scope>
</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>
</project>

View File

@ -77,48 +77,35 @@ public class LDAPLoginModule implements LoginModule {
protected DirContext context;
private Subject subject;
private CallbackHandler handler;
private String initialContextFactory;
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 CallbackHandler handler;
private LDAPLoginProperty [] config;
private String username;
private MessageFormat userSearchMatchingFormat;
private MessageFormat roleSearchMatchingFormat;
private boolean userSearchSubtreeBool;
private boolean roleSearchSubtreeBool;
private Set<GroupPrincipal> groups = new HashSet<GroupPrincipal>();
public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
this.subject = subject;
this.handler = callbackHandler;
initialContextFactory = (String)options.get(INITIAL_CONTEXT_FACTORY);
connectionURL = (String)options.get(CONNECTION_URL);
connectionUsername = (String)options.get(CONNECTION_USERNAME);
connectionPassword = (String)options.get(CONNECTION_PASSWORD);
connectionProtocol = (String)options.get(CONNECTION_PROTOCOL);
authentication = (String)options.get(AUTHENTICATION);
userBase = (String)options.get(USER_BASE);
String userSearchMatching = (String)options.get(USER_SEARCH_MATCHING);
String userSearchSubtree = (String)options.get(USER_SEARCH_SUBTREE);
roleBase = (String)options.get(ROLE_BASE);
roleName = (String)options.get(ROLE_NAME);
String roleSearchMatching = (String)options.get(ROLE_SEARCH_MATCHING);
String roleSearchSubtree = (String)options.get(ROLE_SEARCH_SUBTREE);
userRoleName = (String)options.get(USER_ROLE_NAME);
userSearchMatchingFormat = new MessageFormat(userSearchMatching);
roleSearchMatchingFormat = new MessageFormat(roleSearchMatching);
userSearchSubtreeBool = Boolean.valueOf(userSearchSubtree).booleanValue();
roleSearchSubtreeBool = Boolean.valueOf(roleSearchSubtree).booleanValue();
config = new LDAPLoginProperty [] {
new LDAPLoginProperty (INITIAL_CONTEXT_FACTORY, (String)options.get(INITIAL_CONTEXT_FACTORY)),
new LDAPLoginProperty (CONNECTION_URL, (String)options.get(CONNECTION_URL)),
new LDAPLoginProperty (CONNECTION_USERNAME, (String)options.get(CONNECTION_USERNAME)),
new LDAPLoginProperty (CONNECTION_PASSWORD, (String)options.get(CONNECTION_PASSWORD)),
new LDAPLoginProperty (CONNECTION_PROTOCOL, (String)options.get(CONNECTION_PROTOCOL)),
new LDAPLoginProperty (AUTHENTICATION, (String)options.get(AUTHENTICATION)),
new LDAPLoginProperty (USER_BASE, (String)options.get(USER_BASE)),
new LDAPLoginProperty (USER_SEARCH_MATCHING, (String)options.get(USER_SEARCH_MATCHING)),
new LDAPLoginProperty (USER_SEARCH_SUBTREE, (String)options.get(USER_SEARCH_SUBTREE)),
new LDAPLoginProperty (ROLE_BASE, (String)options.get(ROLE_BASE)),
new LDAPLoginProperty (ROLE_NAME, (String)options.get(ROLE_NAME)),
new LDAPLoginProperty (ROLE_SEARCH_MATCHING, (String)options.get(ROLE_SEARCH_MATCHING)),
new LDAPLoginProperty (ROLE_SEARCH_SUBTREE, (String)options.get(ROLE_SEARCH_SUBTREE)),
new LDAPLoginProperty (USER_ROLE_NAME, (String)options.get(USER_ROLE_NAME)),
};
}
public boolean login() throws LoginException {
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("User name");
@ -130,12 +117,17 @@ public class LDAPLoginModule implements LoginModule {
} catch (UnsupportedCallbackException uce) {
throw (LoginException)new LoginException().initCause(uce);
}
String password;
username = ((NameCallback)callbacks[0]).getName();
String password = new String(((PasswordCallback)callbacks[1]).getPassword());
if (username == null || "".equals(username) || password == null || "".equals(password)) {
return false;
}
if (username == null)
return false;
if (((PasswordCallback)callbacks[1]).getPassword() != null)
password = new String(((PasswordCallback)callbacks[1]).getPassword());
else
password="";
try {
boolean result = authenticate(username, password);
@ -179,8 +171,17 @@ public class LDAPLoginModule implements LoginModule {
protected boolean authenticate(String username, String password) throws Exception {
MessageFormat userSearchMatchingFormat;
boolean userSearchSubtreeBool;
DirContext context = null;
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 {
@ -196,14 +197,14 @@ public class LDAPLoginModule implements LoginModule {
// setup attributes
ArrayList<String> list = new ArrayList<String>();
if (userRoleName != null) {
list.add(userRoleName);
if (isLoginPropertySet(USER_ROLE_NAME)) {
list.add(getLDAPPropertyValue(USER_ROLE_NAME));
}
String[] attribs = new String[list.size()];
list.toArray(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()) {
return false;
@ -216,7 +217,7 @@ public class LDAPLoginModule implements LoginModule {
}
NameParser parser = context.getNameParser("");
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 name = contextName.addAll(baseName);
name = name.addAll(entryName);
@ -227,8 +228,8 @@ public class LDAPLoginModule implements LoginModule {
return false;
}
ArrayList<String> roles = null;
if (userRoleName != null) {
roles = addAttributeValues(userRoleName, attrs, roles);
if (isLoginPropertySet(USER_ROLE_NAME)) {
roles = addAttributeValues(getLDAPPropertyValue(USER_ROLE_NAME), attrs, roles);
}
// 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 {
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) {
list = new ArrayList<String>();
}
if (roleName == null || "".equals(roleName)) {
if (!isLoginPropertySet(ROLE_NAME)) {
return list;
}
String filter = roleSearchMatchingFormat.format(new String[] {
@ -271,14 +277,14 @@ public class LDAPLoginModule implements LoginModule {
} else {
constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE);
}
NamingEnumeration results = context.search(roleBase, filter, constraints);
NamingEnumeration results = context.search(getLDAPPropertyValue(ROLE_BASE), filter, constraints);
while (results.hasMore()) {
SearchResult result = (SearchResult)results.next();
Attributes attrs = result.getAttributes();
if (attrs == null) {
continue;
}
list = addAttributeValues(roleName, attrs, list);
list = addAttributeValues(getLDAPPropertyValue(ROLE_NAME), attrs, list);
}
return list;
@ -325,14 +331,14 @@ public class LDAPLoginModule implements LoginModule {
log.debug("Authentication failed for dn=" + dn);
}
if (connectionUsername != null) {
context.addToEnvironment(Context.SECURITY_PRINCIPAL, connectionUsername);
if (isLoginPropertySet(CONNECTION_USERNAME)) {
context.addToEnvironment(Context.SECURITY_PRINCIPAL, getLDAPPropertyValue(CONNECTION_USERNAME));
} else {
context.removeFromEnvironment(Context.SECURITY_PRINCIPAL);
}
if (connectionPassword != null) {
context.addToEnvironment(Context.SECURITY_CREDENTIALS, connectionPassword);
if (isLoginPropertySet(CONNECTION_PASSWORD)) {
context.addToEnvironment(Context.SECURITY_CREDENTIALS, getLDAPPropertyValue(CONNECTION_PASSWORD));
} else {
context.removeFromEnvironment(Context.SECURITY_CREDENTIALS);
}
@ -361,22 +367,18 @@ public class LDAPLoginModule implements LoginModule {
}
protected DirContext open() throws NamingException {
if (context != null) {
return context;
}
try {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
if (connectionUsername != null || !"".equals(connectionUsername)) {
env.put(Context.SECURITY_PRINCIPAL, connectionUsername);
env.put(Context.INITIAL_CONTEXT_FACTORY, getLDAPPropertyValue(INITIAL_CONTEXT_FACTORY));
if (isLoginPropertySet(CONNECTION_USERNAME)) {
env.put(Context.SECURITY_PRINCIPAL, getLDAPPropertyValue(CONNECTION_USERNAME));
}
if (connectionPassword != null || !"".equals(connectionPassword)) {
env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
if (isLoginPropertySet(CONNECTION_PASSWORD)) {
env.put(Context.SECURITY_CREDENTIALS, getLDAPPropertyValue(CONNECTION_PASSWORD));
}
env.put(Context.SECURITY_PROTOCOL, connectionProtocol);
env.put(Context.PROVIDER_URL, connectionURL);
env.put(Context.SECURITY_AUTHENTICATION, authentication);
env.put(Context.SECURITY_PROTOCOL, getLDAPPropertyValue(CONNECTION_PROTOCOL));
env.put(Context.PROVIDER_URL, getLDAPPropertyValue(CONNECTION_URL));
env.put(Context.SECURITY_AUTHENTICATION, getLDAPPropertyValue(AUTHENTICATION));
context = new InitialDirContext(env);
} catch (NamingException e) {
@ -385,5 +387,20 @@ public class LDAPLoginModule implements LoginModule {
}
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;
import java.io.File;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URL;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.NameClassPair;
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.LoginException;
import junit.framework.TestCase;
import org.apache.activemq.jaas.ldap.MutableServerStartupConfiguration;
import org.apache.activemq.jaas.ldap.ServerContextFactory;
import org.apache.ldap.server.configuration.ShutdownConfiguration;
import org.apache.ldap.server.jndi.CoreContextFactory;
import org.apache.directory.server.core.integ.Level;
import org.apache.directory.server.core.integ.annotations.ApplyLdifs;
import org.apache.directory.server.core.integ.annotations.CleanupLevel;
import org.apache.directory.server.integ.SiRunner;
import org.apache.directory.server.ldap.LdapService;
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 CREDENTIALS = "secret";
public void testNothing() {
}
@SuppressWarnings("unchecked")
@Test
public void testRunning() throws Exception {
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.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, PRINCIPAL);
env.put(Context.SECURITY_CREDENTIALS, CREDENTIALS);
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();
NamingEnumeration list = ctx.list("ou=system");
@ -85,8 +106,9 @@ public class LDAPLoginModuleTest extends TestCase {
assertTrue(set.contains("prefNodeName=sysPrefRoot"));
}
public void xtestLogin() throws LoginException {
@Test
public void testLogin() throws LoginException {
LoginContext context = new LoginContext("LDAPLogin", new CallbackHandler() {
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
@ -104,39 +126,4 @@ public class LDAPLoginModuleTest extends TestCase {
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.out.println("Path to login config: " + path);
}
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,
* 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.
* limitations under the License.
*/
PropertiesLogin {
org.apache.activemq.jaas.PropertiesLoginModule required
@ -25,11 +25,18 @@ LDAPLogin {
org.apache.activemq.jaas.LDAPLoginModule required
debug=true
initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
connectionURL="ldap://localhost:9389"
connectionURL="ldap://localhost:1024"
connectionUsername="uid=admin,ou=system"
connectionPassword=secret
connectionProtocol=s
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>
<cglib-version>2.0</cglib-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>
<commons-dbcp-version>1.2.2</commons-dbcp-version>
<commons-httpclient-version>2.0.1</commons-httpclient-version>
@ -55,18 +55,19 @@
<directory-asn1-version>0.3.2</directory-asn1-version>
<directory-kerboros-version>0.5</directory-kerboros-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>
<howl-version>0.1.8</howl-version>
<hsqldb-version>1.7.2.2</hsqldb-version>
<jdom-version>1.0</jdom-version>
<jetty-version>6.1.9</jetty-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>
<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-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>
<regexp-version>1.3</regexp-version>
<rome-version>0.8</rome-version>
@ -853,70 +854,6 @@
<version>${jdom-version}</version>
</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>
<groupId>p2psockets</groupId>
<artifactId>p2psockets-core</artifactId>