From: <sha...@us...> - 2010-07-31 17:46:41
|
Revision: 12168 http://exist.svn.sourceforge.net/exist/?rev=12168&view=rev Author: shabanovd Date: 2010-07-31 17:46:32 +0000 (Sat, 31 Jul 2010) Log Message: ----------- [ignore] LDAP realm authentication Modified Paths: -------------- trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java Added Paths: ----------- trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/ trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LdapContextFactory.java trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LdapUtils.java trunk/eXist/extensions/security/ldap/test/org/ trunk/eXist/extensions/security/ldap/test/org/exist/ trunk/eXist/extensions/security/ldap/test/org/exist/security/ trunk/eXist/extensions/security/ldap/test/org/exist/security/realm/ trunk/eXist/extensions/security/ldap/test/org/exist/security/realm/ldap/ trunk/eXist/extensions/security/ldap/test/org/exist/security/realm/ldap/LDAPRealmTest.java Removed Paths: ------------- trunk/eXist/extensions/security/ldap/src/org/exist/security/ldap/ Modified: trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java =================================================================== --- trunk/eXist/extensions/security/ldap/src/org/exist/security/ldap/LDAPRealm.java 2010-07-31 08:08:18 UTC (rev 12147) +++ trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java 2010-07-31 17:46:32 UTC (rev 12168) @@ -19,14 +19,24 @@ * * $Id$ */ -package org.exist.security.ldap; +package org.exist.security.realm.ldap; import java.util.Collection; +import javax.naming.NamingException; +import javax.naming.ldap.LdapContext; + +import org.apache.log4j.Logger; import org.exist.EXistException; +import org.exist.config.Configurable; +import org.exist.config.Configuration; +import org.exist.config.Configurator; +import org.exist.config.annotation.*; +import org.exist.security.AuthenticationException; import org.exist.security.Group; import org.exist.security.PermissionDeniedException; import org.exist.security.User; +import org.exist.security.UserImpl; import org.exist.security.realm.Realm; import org.exist.storage.DBBroker; @@ -34,9 +44,34 @@ * @author <a href="mailto:sha...@gm...">Dmitriy Shabanov</a> * */ -public class LDAPRealm implements Realm { +@ConfigurationClass("LDAP") +public class LDAPRealm implements Realm, Configurable { - @Override + private final static Logger LOG = Logger.getLogger(LDAPRealm.class); + + private LdapContextFactory ldapContextFactory = null; + + private Configuration configuration = null; + + public LDAPRealm(Configuration config) { + configuration = Configurator.configure(this, config); + } + + protected LdapContextFactory ensureContextFactory() { + if (this.ldapContextFactory == null) { + + if (LOG.isDebugEnabled()) { + LOG.debug("No LdapContextFactory specified - creating a default instance."); + } + + LdapContextFactory factory = new LdapContextFactory(configuration); + + this.ldapContextFactory = factory; + } + return this.ldapContextFactory; + } + + @Override public String getId() { // TODO Auto-generated method stub return null; @@ -101,5 +136,32 @@ // TODO Auto-generated method stub } + + public User authenticate(String username, Object credentials) throws AuthenticationException { + // Binds using the username and password provided by the user. + LdapContext ctx = null; + try { + ctx = ensureContextFactory().getLdapContext(username, String.valueOf(credentials)); + + } catch (NamingException e) { + throw new AuthenticationException(AuthenticationException.UNNOWN_EXCEPTION, e.getMessage()); + + } finally { + LdapUtils.closeContext(ctx); + } + + return new UserImpl(this, username); + } + //configurable methods + @Override + public boolean isConfigured() { + return (configuration != null); + } + + @Override + public Configuration getConfiguration() { + return configuration; + } + } Added: trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LdapContextFactory.java =================================================================== --- trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LdapContextFactory.java (rev 0) +++ trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LdapContextFactory.java 2010-07-31 17:46:32 UTC (rev 12168) @@ -0,0 +1,131 @@ +/* + * eXist Open Source Native XML Database + * Copyright (C) 2010 The eXist Project + * http://exist-db.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + */ +package org.exist.security.realm.ldap; + +import java.text.MessageFormat; +import java.util.Hashtable; +import java.util.Map; + +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.ldap.InitialLdapContext; +import javax.naming.ldap.LdapContext; + +import org.apache.log4j.Logger; +import org.exist.config.Configurable; +import org.exist.config.Configuration; +import org.exist.config.Configurator; +import org.exist.config.annotation.ConfigurationClass; +import org.exist.config.annotation.ConfigurationField; + +/** + * @author <a href="mailto:sha...@gm...">Dmitriy Shabanov</a> + * + */ +@ConfigurationClass("context") +public class LdapContextFactory implements Configurable { + + protected final static Logger LOG = Logger.getLogger(LdapContextFactory.class); + + protected static final String SUN_CONNECTION_POOLING_PROPERTY = "com.sun.jndi.ldap.connect.pool"; + + protected String authentication = "simple"; + + @ConfigurationField("principalPattern") + protected String principalPattern = null; + private MessageFormat principalPatternFormat; + + @ConfigurationField("url") + protected String url = null; + + protected String contextFactoryClassName = "com.sun.jndi.ldap.LdapCtxFactory"; + + protected String systemUsername = null; + + protected String systemPassword = null; + + private boolean usePooling = true; + + private Map<String, String> additionalEnvironment; + + private Configuration configuration = null; + + protected LdapContextFactory(Configuration config) { + configuration = Configurator.configure(this, config); + + if (principalPattern != null) + principalPatternFormat = new MessageFormat(principalPattern); + } + + public LdapContext getSystemLdapContext() throws NamingException { + return getLdapContext(systemUsername, systemPassword); + } + + public LdapContext getLdapContext(String username, String password) throws NamingException { + if (url == null) + throw new IllegalStateException("An LDAP URL must be specified of the form ldap://<hostname>:<port>"); + + if (username != null && principalPattern != null) { + username = principalPatternFormat.format(new String[] { username }); + } + + Hashtable<String, String> env = new Hashtable<String, String>(); + + env.put(Context.SECURITY_AUTHENTICATION, authentication); + if (username != null) { + env.put(Context.SECURITY_PRINCIPAL, username); + } + if (password != null) { + env.put(Context.SECURITY_CREDENTIALS, password); + } + env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactoryClassName); + env.put(Context.PROVIDER_URL, url); + + // Only pool connections for system contexts + if (usePooling && username != null && username.equals(systemUsername)) { + // Enable connection pooling + env.put(SUN_CONNECTION_POOLING_PROPERTY, "true"); + } + + if (additionalEnvironment != null) { + env.putAll(additionalEnvironment); + } + + if (LOG.isDebugEnabled()) { + LOG.debug("Initializing LDAP context using URL [" + url + "] and username [" + username + "] " + + "with pooling [" + (usePooling ? "enabled" : "disabled") + "]"); + } + + return new InitialLdapContext(env, null); + } + + //configurable methods + @Override + public boolean isConfigured() { + return (configuration != null); + } + + @Override + public Configuration getConfiguration() { + return configuration; + } +} Added: trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LdapUtils.java =================================================================== --- trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LdapUtils.java (rev 0) +++ trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LdapUtils.java 2010-07-31 17:46:32 UTC (rev 12168) @@ -0,0 +1,48 @@ +/* + * eXist Open Source Native XML Database + * Copyright (C) 2010 The eXist Project + * http://exist-db.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + */ +package org.exist.security.realm.ldap; + +import javax.naming.NamingException; +import javax.naming.ldap.LdapContext; + +import org.apache.log4j.Logger; + +/** + * @author <a href="mailto:sha...@gm...">Dmitriy Shabanov</a> + * + */ +public class LdapUtils { + + protected final static Logger LOG = Logger.getLogger(LdapUtils.class); + + public static void closeContext(LdapContext ctx) { + try { + if (ctx != null) { + ctx.close(); + } + } catch (NamingException e) { + if (LOG.isDebugEnabled()) { + LOG.error("Exception while closing LDAP context. ", e); + } + } + } +} Added: trunk/eXist/extensions/security/ldap/test/org/exist/security/realm/ldap/LDAPRealmTest.java =================================================================== --- trunk/eXist/extensions/security/ldap/test/org/exist/security/realm/ldap/LDAPRealmTest.java (rev 0) +++ trunk/eXist/extensions/security/ldap/test/org/exist/security/realm/ldap/LDAPRealmTest.java 2010-07-31 17:46:32 UTC (rev 12168) @@ -0,0 +1,87 @@ +/* + * eXist Open Source Native XML Database + * Copyright (C) 2010 The eXist Project + * http://exist-db.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + */ +package org.exist.security.realm.ldap; + +import static org.junit.Assert.*; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import org.exist.config.Configuration; +import org.exist.config.Configurator; +import org.exist.security.AuthenticationException; +import org.exist.security.User; +import org.exist.security.realm.ldap.LDAPRealm; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * @author <a href="mailto:sha...@gm...">Dmitriy Shabanov</a> + * + */ +public class LDAPRealmTest { + + private static String config = + "<LDAP>" + + " <context " + + " principalPattern='cn={0},dc=local' " + + " url='ldap://localhost:389'/>" + + "</LDAP>"; + + private static LDAPRealm realm; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + InputStream is = new ByteArrayInputStream(config.getBytes("UTF-8")); + + Configuration config = Configurator.parse(is); + + realm = new LDAPRealm(config); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + /** + * Test method for {@link org.exist.security.realm.ldap.LDAPRealm#authenticate(java.lang.String, java.lang.Object)}. + */ + @Test + public void testAuthenticate() { + User account = null; + try { + account = realm.authenticate("admin", "passwd"); + } catch (AuthenticationException e) { + fail(e.getMessage()); + } + + assertNotNull(account); + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |