KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > activemq > jaas > LDAPLoginModule


1 /**
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one or more
4  * contributor license agreements. See the NOTICE file distributed with
5  * this work for additional information regarding copyright ownership.
6  * The ASF licenses this file to You under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with
8  * the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package org.apache.activemq.jaas;
19
20 import java.io.IOException JavaDoc;
21 import java.text.MessageFormat JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.HashSet JavaDoc;
24 import java.util.Hashtable JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.Set JavaDoc;
28 import javax.naming.AuthenticationException JavaDoc;
29 import javax.naming.CommunicationException JavaDoc;
30 import javax.naming.Context JavaDoc;
31 import javax.naming.Name JavaDoc;
32 import javax.naming.NameParser JavaDoc;
33 import javax.naming.NamingEnumeration JavaDoc;
34 import javax.naming.NamingException JavaDoc;
35 import javax.naming.directory.Attribute JavaDoc;
36 import javax.naming.directory.Attributes JavaDoc;
37 import javax.naming.directory.DirContext JavaDoc;
38 import javax.naming.directory.InitialDirContext JavaDoc;
39 import javax.naming.directory.SearchControls JavaDoc;
40 import javax.naming.directory.SearchResult JavaDoc;
41 import javax.security.auth.Subject JavaDoc;
42 import javax.security.auth.callback.Callback JavaDoc;
43 import javax.security.auth.callback.CallbackHandler JavaDoc;
44 import javax.security.auth.callback.NameCallback JavaDoc;
45 import javax.security.auth.callback.PasswordCallback JavaDoc;
46 import javax.security.auth.callback.UnsupportedCallbackException JavaDoc;
47 import javax.security.auth.login.LoginException JavaDoc;
48 import javax.security.auth.login.FailedLoginException JavaDoc;
49 import javax.security.auth.spi.LoginModule JavaDoc;
50
51 import org.apache.commons.logging.Log;
52 import org.apache.commons.logging.LogFactory;
53
54
55 /**
56  * @version $Rev: $ $Date: $
57  */

58 public class LDAPLoginModule implements LoginModule JavaDoc {
59
60     private static Log log = LogFactory.getLog(LDAPLoginModule.class);
61
62     private Subject JavaDoc subject;
63     private CallbackHandler JavaDoc handler;
64
65     private static final String JavaDoc INITIAL_CONTEXT_FACTORY = "initialContextFactory";
66     private static final String JavaDoc CONNECTION_URL = "connectionURL";
67     private static final String JavaDoc CONNECTION_USERNAME = "connectionUsername";
68     private static final String JavaDoc CONNECTION_PASSWORD = "connectionPassword";
69     private static final String JavaDoc CONNECTION_PROTOCOL = "connectionProtocol";
70     private static final String JavaDoc AUTHENTICATION = "authentication";
71     private static final String JavaDoc USER_BASE = "userBase";
72     private static final String JavaDoc USER_SEARCH_MATCHING = "userSearchMatching";
73     private static final String JavaDoc USER_SEARCH_SUBTREE = "userSearchSubtree";
74     private static final String JavaDoc ROLE_BASE = "roleBase";
75     private static final String JavaDoc ROLE_NAME = "roleName";
76     private static final String JavaDoc ROLE_SEARCH_MATCHING = "roleSearchMatching";
77     private static final String JavaDoc ROLE_SEARCH_SUBTREE = "roleSearchSubtree";
78     private static final String JavaDoc USER_ROLE_NAME = "userRoleName";
79
80     private String JavaDoc initialContextFactory;
81     private String JavaDoc connectionURL;
82     private String JavaDoc connectionUsername;
83     private String JavaDoc connectionPassword;
84     private String JavaDoc connectionProtocol;
85     private String JavaDoc authentication;
86     private String JavaDoc userBase;
87     private String JavaDoc roleBase;
88     private String JavaDoc roleName;
89     private String JavaDoc userRoleName;
90
91     private String JavaDoc username;
92
93     protected DirContext JavaDoc context = null;
94
95     private MessageFormat JavaDoc userSearchMatchingFormat;
96     private MessageFormat JavaDoc roleSearchMatchingFormat;
97
98     private boolean userSearchSubtreeBool = false;
99     private boolean roleSearchSubtreeBool = false;
100
101     Set JavaDoc groups = new HashSet JavaDoc();
102
103     public void initialize(Subject JavaDoc subject, CallbackHandler JavaDoc callbackHandler, Map JavaDoc sharedState, Map JavaDoc options) {
104         this.subject = subject;
105         this.handler = callbackHandler;
106         initialContextFactory = (String JavaDoc) options.get(INITIAL_CONTEXT_FACTORY);
107         connectionURL = (String JavaDoc) options.get(CONNECTION_URL);
108         connectionUsername = (String JavaDoc) options.get(CONNECTION_USERNAME);
109         connectionPassword = (String JavaDoc) options.get(CONNECTION_PASSWORD);
110         connectionProtocol = (String JavaDoc) options.get(CONNECTION_PROTOCOL);
111         authentication = (String JavaDoc) options.get(AUTHENTICATION);
112         userBase = (String JavaDoc) options.get(USER_BASE);
113         String JavaDoc userSearchMatching = (String JavaDoc) options.get(USER_SEARCH_MATCHING);
114         String JavaDoc userSearchSubtree = (String JavaDoc) options.get(USER_SEARCH_SUBTREE);
115         roleBase = (String JavaDoc) options.get(ROLE_BASE);
116         roleName = (String JavaDoc) options.get(ROLE_NAME);
117         String JavaDoc roleSearchMatching = (String JavaDoc) options.get(ROLE_SEARCH_MATCHING);
118         String JavaDoc roleSearchSubtree = (String JavaDoc) options.get(ROLE_SEARCH_SUBTREE);
119         userRoleName = (String JavaDoc) options.get(USER_ROLE_NAME);
120         userSearchMatchingFormat = new MessageFormat JavaDoc(userSearchMatching);
121         roleSearchMatchingFormat = new MessageFormat JavaDoc(roleSearchMatching);
122         userSearchSubtreeBool = new Boolean JavaDoc(userSearchSubtree).booleanValue();
123         roleSearchSubtreeBool = new Boolean JavaDoc(roleSearchSubtree).booleanValue();
124     }
125
126     public boolean login() throws LoginException JavaDoc {
127         Callback JavaDoc[] callbacks = new Callback JavaDoc[2];
128
129         callbacks[0] = new NameCallback JavaDoc("User name");
130         callbacks[1] = new PasswordCallback JavaDoc("Password", false);
131         try {
132             handler.handle(callbacks);
133         } catch (IOException JavaDoc ioe) {
134             throw (LoginException JavaDoc) new LoginException JavaDoc().initCause(ioe);
135         } catch (UnsupportedCallbackException JavaDoc uce) {
136             throw (LoginException JavaDoc) new LoginException JavaDoc().initCause(uce);
137         }
138         username = ((NameCallback JavaDoc) callbacks[0]).getName();
139         String JavaDoc password = new String JavaDoc(((PasswordCallback JavaDoc) callbacks[1]).getPassword());
140
141         if (username == null || "".equals(username) || password == null || "".equals(password)) {
142             return false;
143         }
144
145         try {
146             boolean result = authenticate(username, password);
147             if(!result) {
148                 throw new FailedLoginException JavaDoc();
149             } else {
150                 return true;
151             }
152         } catch (Exception JavaDoc e) {
153             throw (LoginException JavaDoc) new LoginException JavaDoc("LDAP Error").initCause(e);
154         }
155     }
156
157     public boolean logout() throws LoginException JavaDoc {
158         username = null;
159         return true;
160     }
161
162     public boolean commit() throws LoginException JavaDoc {
163         Set JavaDoc principals = subject.getPrincipals();
164         principals.add(new UserPrincipal(username));
165         Iterator JavaDoc iter = groups.iterator();
166         while (iter.hasNext()) {
167             principals.add(iter.next());
168         }
169         return true;
170     }
171
172     public boolean abort() throws LoginException JavaDoc {
173         username = null;
174         return true;
175     }
176
177     protected void close(DirContext JavaDoc context) {
178         try {
179             context.close();
180         } catch (Exception JavaDoc e) {
181             log.error(e);
182         }
183     }
184
185     protected boolean authenticate(String JavaDoc username, String JavaDoc password) throws Exception JavaDoc {
186
187         DirContext JavaDoc context = null;
188         context = open();
189
190         try {
191
192             String JavaDoc filter = userSearchMatchingFormat.format(new String JavaDoc[]{username});
193             SearchControls JavaDoc constraints = new SearchControls JavaDoc();
194             if (userSearchSubtreeBool) {
195                 constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
196             } else {
197                 constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE);
198             }
199
200             //setup attributes
201
ArrayList JavaDoc list = new ArrayList JavaDoc();
202             if (userRoleName != null) {
203                 list.add(userRoleName);
204             }
205             String JavaDoc[] attribs = new String JavaDoc[list.size()];
206             list.toArray(attribs);
207             constraints.setReturningAttributes(attribs);
208
209
210             NamingEnumeration JavaDoc results = context.search(userBase, filter, constraints);
211
212             if (results == null || !results.hasMore()) {
213                 return false;
214             }
215
216             SearchResult JavaDoc result = (SearchResult JavaDoc) results.next();
217
218             if (results.hasMore()) {
219                 //ignore for now
220
}
221             NameParser JavaDoc parser = context.getNameParser("");
222             Name JavaDoc contextName = parser.parse(context.getNameInNamespace());
223             Name JavaDoc baseName = parser.parse(userBase);
224             Name JavaDoc entryName = parser.parse(result.getName());
225             Name JavaDoc name = contextName.addAll(baseName);
226             name = name.addAll(entryName);
227             String JavaDoc dn = name.toString();
228
229             Attributes JavaDoc attrs = result.getAttributes();
230             if (attrs == null) {
231                 return false;
232             }
233             ArrayList JavaDoc roles = null;
234             if (userRoleName != null) {
235                 roles = addAttributeValues(userRoleName, attrs, roles);
236             }
237
238             //check the credentials by binding to server
239
if (bindUser(context, dn, password)) {
240                 //if authenticated add more roles
241
roles = getRoles(context, dn, username, roles);
242                 for (int i = 0; i < roles.size(); i++) {
243                     groups.add(new GroupPrincipal((String JavaDoc) roles.get(i)));
244                 }
245             } else {
246                 return false;
247             }
248         } catch (CommunicationException JavaDoc e) {
249
250         } catch (NamingException JavaDoc e) {
251             if (context != null) {
252                 close(context);
253             }
254             return false;
255         }
256
257
258         return true;
259     }
260
261     protected ArrayList JavaDoc getRoles(DirContext JavaDoc context, String JavaDoc dn, String JavaDoc username, ArrayList JavaDoc currentRoles) throws NamingException JavaDoc {
262         ArrayList JavaDoc list = currentRoles;
263         if (list == null) {
264             list = new ArrayList JavaDoc();
265         }
266         if (roleName == null || "".equals(roleName)) {
267             return list;
268         }
269         String JavaDoc filter = roleSearchMatchingFormat.format(new String JavaDoc[]{doRFC2254Encoding(dn), username});
270
271         SearchControls JavaDoc constraints = new SearchControls JavaDoc();
272         if (roleSearchSubtreeBool) {
273             constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
274         } else {
275             constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE);
276         }
277         NamingEnumeration JavaDoc results =
278                 context.search(roleBase, filter, constraints);
279         while (results.hasMore()) {
280             SearchResult JavaDoc result = (SearchResult JavaDoc) results.next();
281             Attributes JavaDoc attrs = result.getAttributes();
282             if (attrs == null) {
283                 continue;
284             }
285             list = addAttributeValues(roleName, attrs, list);
286         }
287         return list;
288
289     }
290
291
292     protected String JavaDoc doRFC2254Encoding(String JavaDoc inputString) {
293         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(inputString.length());
294         for (int i = 0; i < inputString.length(); i++) {
295             char c = inputString.charAt(i);
296             switch (c) {
297                 case '\\':
298                     buf.append("\\5c");
299                     break;
300                 case '*':
301                     buf.append("\\2a");
302                     break;
303                 case '(':
304                     buf.append("\\28");
305                     break;
306                 case ')':
307                     buf.append("\\29");
308                     break;
309                 case '\0':
310                     buf.append("\\00");
311                     break;
312                 default:
313                     buf.append(c);
314                     break;
315             }
316         }
317         return buf.toString();
318     }
319
320     protected boolean bindUser(DirContext JavaDoc context, String JavaDoc dn, String JavaDoc password) throws NamingException JavaDoc {
321         boolean isValid = false;
322
323         context.addToEnvironment(Context.SECURITY_PRINCIPAL, dn);
324         context.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
325         try {
326             context.getAttributes("", null);
327             isValid = true;
328         } catch (AuthenticationException JavaDoc e) {
329             isValid = false;
330             log.debug("Authentication failed for dn=" + dn);
331         }
332
333         if (connectionUsername != null) {
334             context.addToEnvironment(Context.SECURITY_PRINCIPAL,
335                     connectionUsername);
336         } else {
337             context.removeFromEnvironment(Context.SECURITY_PRINCIPAL);
338         }
339
340         if (connectionPassword != null) {
341             context.addToEnvironment(Context.SECURITY_CREDENTIALS,
342                     connectionPassword);
343         } else {
344             context.removeFromEnvironment(Context.SECURITY_CREDENTIALS);
345         }
346
347         return isValid;
348     }
349
350     private ArrayList JavaDoc addAttributeValues(String JavaDoc attrId, Attributes JavaDoc attrs, ArrayList JavaDoc values)
351             throws NamingException JavaDoc
352     {
353
354         if (attrId == null || attrs == null) {
355             return values;
356         }
357         if (values == null) {
358             values = new ArrayList JavaDoc();
359         }
360         Attribute JavaDoc attr = attrs.get(attrId);
361         if (attr == null) {
362             return (values);
363         }
364         NamingEnumeration JavaDoc e = attr.getAll();
365         while (e.hasMore()) {
366             String JavaDoc value = (String JavaDoc) e.next();
367             values.add(value);
368         }
369         return values;
370     }
371
372     protected DirContext JavaDoc open() throws NamingException JavaDoc {
373         if (context != null) {
374             return context;
375         }
376
377         try {
378             Hashtable JavaDoc env = new Hashtable JavaDoc();
379             env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
380             if (connectionUsername != null || !"".equals(connectionUsername)) {
381                 env.put(Context.SECURITY_PRINCIPAL, connectionUsername);
382             }
383             if (connectionPassword != null || !"".equals(connectionPassword)) {
384                 env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
385             }
386             env.put(Context.SECURITY_PROTOCOL, connectionProtocol);
387             env.put(Context.PROVIDER_URL, connectionURL);
388             env.put(Context.SECURITY_AUTHENTICATION, authentication);
389             context = new InitialDirContext JavaDoc(env);
390
391         } catch (NamingException JavaDoc e) {
392             log.error(e);
393             throw e;
394         }
395         return context;
396     }
397
398 }
399
Popular Tags