Revision 504
Added by Matt Jones about 24 years ago
src/edu/ucsb/nceas/metacat/AuthLdap.java | ||
---|---|---|
19 | 19 |
|
20 | 20 |
import javax.naming.AuthenticationException; |
21 | 21 |
import javax.naming.Context; |
22 |
import javax.naming.directory.InitialDirContext; |
|
23 |
import javax.naming.directory.DirContext; |
|
24 | 22 |
import javax.naming.directory.Attribute; |
25 | 23 |
import javax.naming.directory.Attributes; |
24 |
import javax.naming.directory.BasicAttribute; |
|
25 |
import javax.naming.directory.BasicAttributes; |
|
26 |
import javax.naming.directory.DirContext; |
|
27 |
import javax.naming.directory.InitialDirContext; |
|
28 |
import javax.naming.directory.SearchResult; |
|
26 | 29 |
import javax.naming.NamingEnumeration; |
27 | 30 |
import javax.naming.NamingException; |
28 | 31 |
import java.util.Iterator; |
... | ... | |
54 | 57 |
String ldapUrl = util.getOption("ldapurl"); |
55 | 58 |
String ldapBase = util.getOption("ldapbase"); |
56 | 59 |
|
60 |
String distName = null; |
|
57 | 61 |
boolean authenticated = false; |
58 | 62 |
|
59 | 63 |
// Identify service provider to use |
... | ... | |
62 | 66 |
"com.sun.jndi.ldap.LdapCtxFactory"); |
63 | 67 |
env.put(Context.PROVIDER_URL, ldapUrl + ldapBase); |
64 | 68 |
|
65 |
// Authentication information |
|
66 |
env.put(Context.SECURITY_AUTHENTICATION, "simple"); |
|
67 |
env.put(Context.SECURITY_PRINCIPAL, user + "," + ldapBase); |
|
68 |
env.put(Context.SECURITY_CREDENTIALS, password); |
|
69 |
|
|
70 | 69 |
try { |
71 | 70 |
|
72 |
// Bind to the LDAP server |
|
73 |
// If our auth credentials are invalid, an exception will be thrown |
|
74 |
DirContext ctx = new InitialDirContext(env); |
|
75 |
authenticated = true; |
|
71 |
// Get the dn for this uid or cn |
|
72 |
String identifier = getIdentifyingName(user); |
|
73 |
if (identifier != null) { |
|
74 |
distName = identifier + "," + ldapBase; |
|
75 |
// Now that we have the dn, we can authenticate, so |
|
76 |
// authenticate this time when opening the DirContext |
|
77 |
env.put(Context.SECURITY_AUTHENTICATION, "simple"); |
|
78 |
env.put(Context.SECURITY_PRINCIPAL, distName); |
|
79 |
env.put(Context.SECURITY_CREDENTIALS, password); |
|
80 |
// If our auth credentials are invalid, an exception will be thrown |
|
81 |
DirContext ctx = new InitialDirContext(env); |
|
76 | 82 |
|
77 |
// Close the context when we're done |
|
78 |
ctx.close(); |
|
83 |
// If no exception is thrown then authentication succeeded |
|
84 |
authenticated = true; |
|
85 |
|
|
86 |
// Close the context when we're done |
|
87 |
ctx.close(); |
|
88 |
} else { |
|
89 |
util.debugMessage("User not found!"); |
|
90 |
} |
|
91 |
|
|
79 | 92 |
} catch (AuthenticationException ae) { |
80 | 93 |
util.debugMessage("Error authenticating: " + ae); |
81 | 94 |
// NEED TO THROW THE RIGHT EXCEPTION HERE |
... | ... | |
162 | 175 |
|
163 | 176 |
// Authentication information |
164 | 177 |
if ((authuser != null) && (password != null)) { |
178 |
String identifier = getIdentifyingName(authuser); |
|
165 | 179 |
env.put(Context.SECURITY_AUTHENTICATION, "simple"); |
166 |
env.put(Context.SECURITY_PRINCIPAL, authuser + "," + ldapBase);
|
|
180 |
env.put(Context.SECURITY_PRINCIPAL, identifier + "," + ldapBase);
|
|
167 | 181 |
env.put(Context.SECURITY_CREDENTIALS, password); |
168 | 182 |
} |
169 | 183 |
|
170 | 184 |
try { |
171 | 185 |
|
186 |
// Find out the identifying attribute for the user |
|
187 |
String userident = getIdentifyingName(user); |
|
188 |
|
|
172 | 189 |
// Create the initial directory context |
173 | 190 |
DirContext ctx = new InitialDirContext(env); |
174 | 191 |
|
175 |
// Ask for all attributes of the object
|
|
176 |
Attributes attrs = ctx.getAttributes(user); |
|
192 |
// Ask for all attributes of the user
|
|
193 |
Attributes attrs = ctx.getAttributes(userident);
|
|
177 | 194 |
|
178 | 195 |
// Print all of the attributes |
179 | 196 |
NamingEnumeration en = attrs.getAll(); |
... | ... | |
200 | 217 |
} |
201 | 218 |
|
202 | 219 |
/** |
220 |
* Get the identifying name for a given userid or name. This is the name |
|
221 |
* that is used in conjunction withthe LDAP BaseDN to create a |
|
222 |
* distinguished name (dn) for the record |
|
223 |
* |
|
224 |
* @param user the user for which the identifying name is requested |
|
225 |
* @returns String the identifying name for the user, |
|
226 |
* or null if not found |
|
227 |
*/ |
|
228 |
private String getIdentifyingName(String user) |
|
229 |
throws ConnectException |
|
230 |
{ |
|
231 |
MetaCatUtil util = new MetaCatUtil(); |
|
232 |
String ldapUrl = util.getOption("ldapurl"); |
|
233 |
String ldapBase = util.getOption("ldapbase"); |
|
234 |
|
|
235 |
String identifier = null; |
|
236 |
|
|
237 |
// Identify service provider to use |
|
238 |
Hashtable env = new Hashtable(11); |
|
239 |
env.put(Context.INITIAL_CONTEXT_FACTORY, |
|
240 |
"com.sun.jndi.ldap.LdapCtxFactory"); |
|
241 |
env.put(Context.PROVIDER_URL, ldapUrl + ldapBase); |
|
242 |
|
|
243 |
try { |
|
244 |
|
|
245 |
// Bind to the LDAP server, in order to search for the right |
|
246 |
// distinguished name (dn) based on userid (uid) or common name (cn) |
|
247 |
DirContext ctx = new InitialDirContext(env); |
|
248 |
|
|
249 |
// Search for the user id or name using the uid, then cn and sn attributes |
|
250 |
// If we find a record, determine the dn for the record |
|
251 |
util.debugMessage("\nStarting search phase...\n"); |
|
252 |
Attributes matchAttrs = new BasicAttributes(true); |
|
253 |
matchAttrs.put(new BasicAttribute("uid", user)); |
|
254 |
NamingEnumeration answer = ctx.search("", matchAttrs); |
|
255 |
if (answer.hasMore()) { |
|
256 |
SearchResult sr = (SearchResult)answer.next(); |
|
257 |
identifier = sr.getName(); |
|
258 |
util.debugMessage("Found: " + identifier); |
|
259 |
} else { |
|
260 |
Attributes matchAttrs2 = new BasicAttributes(true); |
|
261 |
matchAttrs2.put(new BasicAttribute("cn", user)); |
|
262 |
NamingEnumeration answer2 = ctx.search("", matchAttrs2); |
|
263 |
if (answer2.hasMore()) { |
|
264 |
SearchResult sr = (SearchResult)answer2.next(); |
|
265 |
identifier = sr.getName(); |
|
266 |
util.debugMessage("Found: " + identifier); |
|
267 |
} else { |
|
268 |
Attributes matchAttrs3 = new BasicAttributes(true); |
|
269 |
matchAttrs3.put(new BasicAttribute("sn", user)); |
|
270 |
NamingEnumeration answer3 = ctx.search("", matchAttrs3); |
|
271 |
if (answer3.hasMore()) { |
|
272 |
SearchResult sr = (SearchResult)answer3.next(); |
|
273 |
identifier = sr.getName(); |
|
274 |
util.debugMessage("Found: " + identifier); |
|
275 |
} |
|
276 |
} |
|
277 |
} |
|
278 |
// Close the context when we're done the initial search |
|
279 |
ctx.close(); |
|
280 |
} catch (NamingException e) { |
|
281 |
util.debugMessage("Naming exception while getting dn: " + e); |
|
282 |
// NEED TO THROW THE RIGHT EXCEPTION HERE |
|
283 |
return null; |
|
284 |
} |
|
285 |
|
|
286 |
return identifier; |
|
287 |
} |
|
288 |
|
|
289 |
/** |
|
203 | 290 |
* Test method for the class |
204 | 291 |
*/ |
205 | 292 |
public static void main(String[] args) { |
206 | 293 |
|
207 |
// Provide a user, such as: "cn=Matt Jones"
|
|
294 |
// Provide a user, such as: "Matt Jones", or "jones"
|
|
208 | 295 |
String user = args[0]; |
209 | 296 |
String password = args[1]; |
210 | 297 |
|
... | ... | |
221 | 308 |
} |
222 | 309 |
|
223 | 310 |
if (isValid) { |
224 |
HashMap userInfo = authservice.getAttributes(user); |
|
311 |
HashMap userInfo = authservice.getAttributes(user, user, password);
|
|
225 | 312 |
|
226 | 313 |
// Print all of the attributes |
227 | 314 |
Iterator attList = (Iterator)(((Set)userInfo.keySet()).iterator()); |
228 | 315 |
while (attList.hasNext()) { |
229 | 316 |
String att = (String)attList.next(); |
230 | 317 |
Vector values = (Vector)userInfo.get(att); |
231 |
System.out.println(att + ": " ); |
|
232 | 318 |
Iterator attvalues = values.iterator(); |
233 | 319 |
while (attvalues.hasNext()) { |
234 | 320 |
String value = (String)attvalues.next(); |
235 |
System.out.println(" value: " + value);
|
|
321 |
System.out.println(att + ": " + value);
|
|
236 | 322 |
} |
237 | 323 |
} |
238 | 324 |
} |
Also available in: Unified diff
Fixed the LDAP authentication adapter (AuthLdap.java) so that it now looks up
the distinguished name for a user before attempting to do authentication.
This is because the user's distinguished name can sometimes be based on
their uid attribute, but sometimes be based on their cn (common name)
attribute, or some other attribute. In order to authenticate, we must
be able construct the distinguished name, so we have to look up the
identifying attribute before trying to authenticate. Basically, this
lets us authenticate agains both of the following records:
and
Effectively, this means that the user can type in their user id (uid),
common name (cn), or surname (sn) and we'll still be able to authenticate them.
BugID: 138