Source Code Cross Referenced for DefaultInitialDirContextFactory.java in  » Security » acegi-security » org » acegisecurity » ldap » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Security » acegi security » org.acegisecurity.ldap 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002:         *
003:         * Licensed under the Apache License, Version 2.0 (the "License");
004:         * you may not use this file except in compliance with the License.
005:         * You may obtain a copy of the License at
006:         *
007:         *     http://www.apache.org/licenses/LICENSE-2.0
008:         *
009:         * Unless required by applicable law or agreed to in writing, software
010:         * distributed under the License is distributed on an "AS IS" BASIS,
011:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012:         * See the License for the specific language governing permissions and
013:         * limitations under the License.
014:         */
015:
016:        package org.acegisecurity.ldap;
017:
018:        import org.acegisecurity.AcegiMessageSource;
019:        import org.acegisecurity.BadCredentialsException;
020:
021:        import org.apache.commons.logging.Log;
022:        import org.apache.commons.logging.LogFactory;
023:
024:        import org.springframework.context.MessageSource;
025:        import org.springframework.context.MessageSourceAware;
026:        import org.springframework.context.support.MessageSourceAccessor;
027:
028:        import org.springframework.util.Assert;
029:
030:        import java.util.Hashtable;
031:        import java.util.Map;
032:        import java.util.StringTokenizer;
033:
034:        import javax.naming.CommunicationException;
035:        import javax.naming.Context;
036:        import javax.naming.NamingException;
037:        import javax.naming.OperationNotSupportedException;
038:        import javax.naming.ldap.InitialLdapContext;
039:        import javax.naming.directory.DirContext;
040:        import javax.naming.directory.InitialDirContext;
041:
042:        /**
043:         * Encapsulates the information for connecting to an LDAP server and provides an access point for obtaining
044:         * <tt>DirContext</tt> references.
045:         * <p>
046:         * The directory location is configured using by setting the constructor argument
047:         * <tt>providerUrl</tt>. This should be in the form <tt>ldap://monkeymachine.co.uk:389/dc=acegisecurity,dc=org</tt>.
048:         * The Sun JNDI provider also supports lists of space-separated URLs, each of which will be tried in turn until a
049:         * connection is obtained.
050:         * </p>
051:         * <p>To obtain an initial context, the client calls the <tt>newInitialDirContext</tt> method. There are two
052:         * signatures - one with no arguments and one which allows binding with a specific username and password.
053:         * </p>
054:         * <p>The no-args version will bind anonymously unless a manager login has been configured using the properties
055:         * <tt>managerDn</tt> and <tt>managerPassword</tt>, in which case it will bind as the manager user.</p>
056:         * <p>Connection pooling is enabled by default for anonymous or manager connections, but not when binding as a
057:         * specific user.</p>
058:         *
059:         * @author Robert Sanders
060:         * @author Luke Taylor
061:         * @version $Id: DefaultInitialDirContextFactory.java 1784 2007-02-24 21:00:24Z luke_t $
062:         *
063:         * @see <a href="http://java.sun.com/products/jndi/tutorial/ldap/connect/pool.html">The Java tutorial's guide to LDAP
064:         *      connection pooling</a>
065:         */
066:        public class DefaultInitialDirContextFactory implements 
067:                InitialDirContextFactory, MessageSourceAware {
068:            //~ Static fields/initializers =====================================================================================
069:
070:            private static final Log logger = LogFactory
071:                    .getLog(DefaultInitialDirContextFactory.class);
072:            private static final String CONNECTION_POOL_KEY = "com.sun.jndi.ldap.connect.pool";
073:            private static final String AUTH_TYPE_NONE = "none";
074:
075:            //~ Instance fields ================================================================================================
076:
077:            /** Allows extra environment variables to be added at config time. */
078:            private Map extraEnvVars = null;
079:            protected MessageSourceAccessor messages = AcegiMessageSource
080:                    .getAccessor();
081:
082:            /** Type of authentication within LDAP; default is simple. */
083:            private String authenticationType = "simple";
084:
085:            /**
086:             * The INITIAL_CONTEXT_FACTORY used to create the JNDI Factory. Default is
087:             * "com.sun.jndi.ldap.LdapCtxFactory"; you <b>should not</b> need to set this unless you have unusual needs.
088:             */
089:            private String initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
090:
091:            /**
092:             * If your LDAP server does not allow anonymous searches then you will need to provide a "manager" user's
093:             * DN to log in with.
094:             */
095:            private String managerDn = null;
096:
097:            /** The manager user's password. */
098:            private String managerPassword = "manager_password_not_set";
099:
100:            /** The LDAP url of the server (and root context) to connect to. */
101:            private String providerUrl;
102:
103:            /**
104:             * The root DN. This is worked out from the url. It is used by client classes when forming a full DN for
105:             * bind authentication (for example).
106:             */
107:            private String rootDn = null;
108:
109:            /**
110:             * Use the LDAP Connection pool; if true, then the LDAP environment property
111:             * "com.sun.jndi.ldap.connect.pool" is added to any other JNDI properties.
112:             */
113:            private boolean useConnectionPool = true;
114:
115:            /** Set to true for ldap v3 compatible servers */
116:            private boolean useLdapContext = false;
117:
118:            //~ Constructors ===================================================================================================
119:
120:            /**
121:             * Create and initialize an instance to the LDAP url provided
122:             *
123:             * @param providerUrl a String of the form <code>ldap://localhost:389/base_dn<code>
124:             */
125:            public DefaultInitialDirContextFactory(String providerUrl) {
126:                this .setProviderUrl(providerUrl);
127:            }
128:
129:            //~ Methods ========================================================================================================
130:
131:            /**
132:             * Set the LDAP url
133:             *
134:             * @param providerUrl a String of the form <code>ldap://localhost:389/base_dn<code>
135:             */
136:            private void setProviderUrl(String providerUrl) {
137:                Assert.hasLength(providerUrl,
138:                        "An LDAP connection URL must be supplied.");
139:
140:                this .providerUrl = providerUrl;
141:
142:                StringTokenizer st = new StringTokenizer(providerUrl);
143:
144:                // Work out rootDn from the first URL and check that the other URLs (if any) match
145:                while (st.hasMoreTokens()) {
146:                    String url = st.nextToken();
147:                    String urlRootDn = LdapUtils.parseRootDnFromUrl(url);
148:
149:                    logger.info(" URL '" + url + "', root DN is '" + urlRootDn
150:                            + "'");
151:
152:                    if (rootDn == null) {
153:                        rootDn = urlRootDn;
154:                    } else if (!rootDn.equals(urlRootDn)) {
155:                        throw new IllegalArgumentException(
156:                                "Root DNs must be the same when using multiple URLs");
157:                    }
158:                }
159:
160:                // This doesn't necessarily hold for embedded servers.
161:                //Assert.isTrue(uri.getScheme().equals("ldap"), "Ldap URL must start with 'ldap://'");
162:            }
163:
164:            /**
165:             * Get the LDAP url
166:             *
167:             * @return the url
168:             */
169:            private String getProviderUrl() {
170:                return providerUrl;
171:            }
172:
173:            private InitialDirContext connect(Hashtable env) {
174:                if (logger.isDebugEnabled()) {
175:                    Hashtable envClone = (Hashtable) env.clone();
176:
177:                    if (envClone.containsKey(Context.SECURITY_CREDENTIALS)) {
178:                        envClone.put(Context.SECURITY_CREDENTIALS, "******");
179:                    }
180:
181:                    logger.debug("Creating InitialDirContext with environment "
182:                            + envClone);
183:                }
184:
185:                try {
186:                    return useLdapContext ? new InitialLdapContext(env, null)
187:                            : new InitialDirContext(env);
188:                } catch (NamingException ne) {
189:                    if ((ne instanceof  javax.naming.AuthenticationException)
190:                            || (ne instanceof  OperationNotSupportedException)) {
191:                        throw new BadCredentialsException(
192:                                messages
193:                                        .getMessage(
194:                                                "DefaultIntitalDirContextFactory.badCredentials",
195:                                                "Bad credentials"), ne);
196:                    }
197:
198:                    if (ne instanceof  CommunicationException) {
199:                        throw new LdapDataAccessException(
200:                                messages
201:                                        .getMessage(
202:                                                "DefaultIntitalDirContextFactory.communicationFailure",
203:                                                "Unable to connect to LDAP server"),
204:                                ne);
205:                    }
206:
207:                    throw new LdapDataAccessException(
208:                            messages
209:                                    .getMessage(
210:                                            "DefaultIntitalDirContextFactory.unexpectedException",
211:                                            "Failed to obtain InitialDirContext due to unexpected exception"),
212:                            ne);
213:                }
214:            }
215:
216:            /**
217:             * Sets up the environment parameters for creating a new context.
218:             *
219:             * @return the Hashtable describing the base DirContext that will be created, minus the username/password if any.
220:             */
221:            protected Hashtable getEnvironment() {
222:                Hashtable env = new Hashtable();
223:
224:                env.put(Context.SECURITY_AUTHENTICATION, authenticationType);
225:                env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
226:                env.put(Context.PROVIDER_URL, getProviderUrl());
227:
228:                if (useConnectionPool) {
229:                    env.put(CONNECTION_POOL_KEY, "true");
230:                }
231:
232:                if ((extraEnvVars != null) && (extraEnvVars.size() > 0)) {
233:                    env.putAll(extraEnvVars);
234:                }
235:
236:                return env;
237:            }
238:
239:            /**
240:             * Returns the root DN of the configured provider URL. For example, if the URL is
241:             * <tt>ldap://monkeymachine.co.uk:389/dc=acegisecurity,dc=org</tt> the value will be
242:             * <tt>dc=acegisecurity,dc=org</tt>.
243:             *
244:             * @return the root DN calculated from the path of the LDAP url.
245:             */
246:            public String getRootDn() {
247:                return rootDn;
248:            }
249:
250:            /**
251:             * Connects anonymously unless a manager user has been specified, in which case it will bind as the
252:             * manager.
253:             *
254:             * @return the resulting context object.
255:             */
256:            public DirContext newInitialDirContext() {
257:                if (managerDn != null) {
258:                    return newInitialDirContext(managerDn, managerPassword);
259:                }
260:
261:                Hashtable env = getEnvironment();
262:                env.put(Context.SECURITY_AUTHENTICATION, AUTH_TYPE_NONE);
263:
264:                return connect(env);
265:            }
266:
267:            public DirContext newInitialDirContext(String username,
268:                    String password) {
269:                Hashtable env = getEnvironment();
270:
271:                // Don't pool connections for individual users
272:                if (!username.equals(managerDn)) {
273:                    env.remove(CONNECTION_POOL_KEY);
274:                }
275:
276:                env.put(Context.SECURITY_PRINCIPAL, username);
277:                env.put(Context.SECURITY_CREDENTIALS, password);
278:
279:                return connect(env);
280:            }
281:
282:            public void setAuthenticationType(String authenticationType) {
283:                Assert.hasLength(authenticationType,
284:                        "LDAP Authentication type must not be empty or null");
285:                this .authenticationType = authenticationType;
286:            }
287:
288:            /**
289:             * Sets any custom environment variables which will be added to the those returned
290:             * by the <tt>getEnvironment</tt> method.
291:             *
292:             * @param extraEnvVars extra environment variables to be added at config time.
293:             */
294:            public void setExtraEnvVars(Map extraEnvVars) {
295:                Assert.notNull(extraEnvVars,
296:                        "Extra environment map cannot be null.");
297:                this .extraEnvVars = extraEnvVars;
298:            }
299:
300:            public void setInitialContextFactory(String initialContextFactory) {
301:                Assert.hasLength(initialContextFactory,
302:                        "Initial context factory name cannot be empty or null");
303:                this .initialContextFactory = initialContextFactory;
304:            }
305:
306:            /**
307:             * Sets the directory user to authenticate as when obtaining a context using the
308:             * <tt>newInitialDirContext()</tt> method.
309:             * If no name is supplied then the context will be obtained anonymously.
310:             *
311:             * @param managerDn The name of the "manager" user for default authentication.
312:             */
313:            public void setManagerDn(String managerDn) {
314:                Assert.hasLength(managerDn,
315:                        "Manager user name  cannot be empty or null.");
316:                this .managerDn = managerDn;
317:            }
318:
319:            /**
320:             * Sets the password which will be used in combination with the manager DN.
321:             *
322:             * @param managerPassword The "manager" user's password.
323:             */
324:            public void setManagerPassword(String managerPassword) {
325:                Assert.hasLength(managerPassword,
326:                        "Manager password must not be empty or null.");
327:                this .managerPassword = managerPassword;
328:            }
329:
330:            public void setMessageSource(MessageSource messageSource) {
331:                this .messages = new MessageSourceAccessor(messageSource);
332:            }
333:
334:            /**
335:             * Connection pooling is enabled by default for anonymous or "manager" connections when using the default
336:             * Sun provider. To disable all connection pooling, set this property to false.
337:             *
338:             * @param useConnectionPool whether to pool connections for non-specific users.
339:             */
340:            public void setUseConnectionPool(boolean useConnectionPool) {
341:                this .useConnectionPool = useConnectionPool;
342:            }
343:
344:            public void setUseLdapContext(boolean useLdapContext) {
345:                this.useLdapContext = useLdapContext;
346:            }
347:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.