Revision 3155
Added by Chris Jones almost 18 years ago
src/edu/ucsb/nceas/metacat/AuthLdap.java | ||
---|---|---|
64 | 64 |
* The LDAP authentication service is used to determine if a user |
65 | 65 |
* is authenticated, and whether they are a member of a particular group. |
66 | 66 |
*/ |
67 |
public class AuthLdap |
|
68 |
implements AuthInterface, Runnable { |
|
67 |
public class AuthLdap implements AuthInterface { |
|
69 | 68 |
private MetaCatUtil util = new MetaCatUtil(); |
70 | 69 |
private String ldapUrl; |
71 | 70 |
private String ldapsUrl; |
72 | 71 |
private String ldapBase; |
73 | 72 |
private String referral; |
73 |
private String ldapConnectTimeLimit; |
|
74 |
private int ldapSearchTimeLimit; |
|
75 |
private int ldapSearchCountLimit; |
|
74 | 76 |
private Context referralContext; |
77 |
private String currentReferralInfo; |
|
75 | 78 |
Hashtable env = new Hashtable(11); |
76 | 79 |
private Context rContext; |
77 | 80 |
private String userName; |
... | ... | |
89 | 92 |
this.ldapsUrl = MetaCatUtil.getOption("ldapsurl"); |
90 | 93 |
this.ldapBase = MetaCatUtil.getOption("ldapbase"); |
91 | 94 |
this.referral = MetaCatUtil.getOption("referral"); |
95 |
this.ldapConnectTimeLimit = |
|
96 |
MetaCatUtil.getOption("ldapconnecttimelimit"); |
|
97 |
this.ldapSearchTimeLimit = Integer.parseInt( |
|
98 |
MetaCatUtil.getOption("ldapsearchtimelimit")); |
|
99 |
this.ldapSearchCountLimit = Integer.parseInt( |
|
100 |
MetaCatUtil.getOption("ldapsearchcountlimit")); |
|
101 |
|
|
102 |
// Store referral info for use in building group DNs in getGroups() |
|
103 |
this.currentReferralInfo = ""; |
|
92 | 104 |
} |
93 | 105 |
|
94 | 106 |
/** |
... | ... | |
1229 | 1241 |
* This method will be called by start a thread. |
1230 | 1242 |
* It can handle if a referral exception happend. |
1231 | 1243 |
*/ |
1232 |
public void run() { |
|
1233 |
referralContext = null; |
|
1234 |
DirContext refDirContext = null; |
|
1235 |
boolean moreReferrals = true; |
|
1236 |
String referralInfo = null; |
|
1237 |
//set a while loop is because we don't know if a referral excption contains |
|
1238 |
//another referral exception |
|
1239 |
while (moreReferrals) { |
|
1240 |
try { |
|
1241 |
//revise environment variable |
|
1242 |
referralInfo = (String) refExc.getReferralInfo(); |
|
1243 |
logMetacat.info("Processing referral (pr0): "); |
|
1244 |
logMetacat.info("PROVIDER_URL set to (pr1): " + referralInfo); |
|
1245 |
//env.put(Context.PROVIDER_URL,referralInfo); |
|
1246 |
//env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); |
|
1247 |
//env.put(Context.SECURITY_PRINCIPAL, userName); |
|
1248 |
//env.put(Context.SECURITY_CREDENTIALS, userPassword); |
|
1249 |
//env.put(Context.REFERRAL, "throw"); |
|
1250 |
//logMetacat.info("Processing referral (pr1.info): " + userName,35); |
|
1251 |
//logMetacat.info("Processing referral (pr2)",35); |
|
1252 |
//rContext = refExc.getReferralContext(env); |
|
1253 |
rContext = refExc.getReferralContext(); |
|
1254 |
logMetacat.info("Processing referral (pr3)"); |
|
1255 |
//casting the context to dircontext and it will create a |
|
1256 |
//autherntication or naming exception if DN and password is incorrect |
|
1257 |
referralContext = rContext; |
|
1258 |
refDirContext = (DirContext) rContext; |
|
1259 |
refDirContext.close(); |
|
1260 |
//get context and jump out the while loop |
|
1261 |
moreReferrals = false; |
|
1262 |
logMetacat.info("Processing referral (pr4)"); |
|
1263 |
} //try |
|
1264 |
//if referral have another referral excption |
|
1265 |
catch (ReferralException re) { |
|
1266 |
logMetacat.warn("GOT referral exception (re1): " + re.getMessage()); |
|
1267 |
logMetacat.warn("RE details (re2): " + re.toString(true)); |
|
1268 |
//keep running in while loop |
|
1269 |
moreReferrals = true; |
|
1270 |
//assign refExc to new referral exception re |
|
1271 |
refExc = re; |
|
1272 |
} |
|
1273 |
//catch a authentication exception |
|
1274 |
catch (AuthenticationException ae) { |
|
1275 |
logMetacat.error("Error running referral handler thread (ae1): " + |
|
1276 |
ae.getMessage()); |
|
1277 |
//check if has another referral |
|
1278 |
moreReferrals = refExc.skipReferral(); |
|
1279 |
//don't get the context |
|
1280 |
referralContext = null; |
|
1281 |
} |
|
1282 |
//catch a naming exception |
|
1283 |
catch (NamingException ne) { |
|
1284 |
logMetacat.error("Error running referral handler thread (ne1): " + |
|
1285 |
ne.getMessage()); |
|
1286 |
//check if has another referral |
|
1287 |
moreReferrals = refExc.skipReferral(); |
|
1288 |
//don't get context |
|
1289 |
referralContext = null; |
|
1290 |
} |
|
1291 |
} //while |
|
1292 |
} //run() |
|
1293 |
|
|
1294 |
private class GetGroup |
|
1295 |
implements Runnable { |
|
1296 |
public void run() { |
|
1297 |
referralContext = null; |
|
1298 |
logMetacat.info("getting groups context"); |
|
1299 |
DirContext refDirContext = null; |
|
1300 |
boolean moreReferrals = true; |
|
1301 |
//set a while loop is because we don't know if a referral excption |
|
1302 |
//contains another referral exception |
|
1303 |
while (moreReferrals) { |
|
1304 |
try { |
|
1305 |
//revise environment variable |
|
1306 |
String refInfo = null; |
|
1307 |
refInfo = (String) refExc.getReferralInfo(); |
|
1308 |
if (refInfo != null) { |
|
1309 |
logMetacat.info("Referral in thread to: " + |
|
1310 |
refInfo.toString()); |
|
1311 |
} |
|
1312 |
else { |
|
1313 |
logMetacat.info("getting refInfo Manually"); |
|
1314 |
refInfo = (String) refExc.getReferralContext().getEnvironment(). |
|
1315 |
get(Context.PROVIDER_URL); |
|
1316 |
} |
|
1317 |
logMetacat.info("refInfo: " + refInfo); |
|
1318 |
|
|
1319 |
env.put(Context.INITIAL_CONTEXT_FACTORY, |
|
1320 |
"com.sun.jndi.ldap.LdapCtxFactory"); |
|
1321 |
env.put(Context.REFERRAL, "throw"); |
|
1322 |
env.put(Context.PROVIDER_URL, refInfo); |
|
1323 |
|
|
1324 |
logMetacat.info("creating referralContext"); |
|
1325 |
referralContext = new InitialDirContext(env); |
|
1326 |
logMetacat.info("referralContext created"); |
|
1327 |
//get context and jump out the while loop |
|
1328 |
moreReferrals = false; |
|
1329 |
} //try |
|
1330 |
catch (ReferralException re) { |
|
1331 |
//keep running in while loop |
|
1332 |
moreReferrals = true; |
|
1333 |
//assign refExc to new referral exception re |
|
1334 |
refExc = re; |
|
1335 |
} |
|
1336 |
catch (AuthenticationException ae) { |
|
1337 |
logMetacat.error("Error running referral handler thread (ae2): " + |
|
1338 |
ae.getMessage()); |
|
1339 |
//check if has another referral |
|
1340 |
moreReferrals = refExc.skipReferral(); |
|
1341 |
//don't get the context |
|
1342 |
referralContext = null; |
|
1343 |
} |
|
1344 |
catch (NamingException ne) { |
|
1345 |
logMetacat.error("Error running referral handler thread (ne2): " + |
|
1346 |
ne.getMessage()); |
|
1347 |
//check if has another referral |
|
1348 |
moreReferrals = refExc.skipReferral(); |
|
1349 |
//don't get context |
|
1350 |
referralContext = null; |
|
1351 |
} |
|
1352 |
} //while |
|
1353 |
} //run() |
|
1354 |
} |
|
1355 | 1244 |
} |
Also available in: Unified diff
As a partial fix to http://bugzilla.ecoinformatics.org/show_bug.cgi?id=2747,
I'm applying 3 patches to AuthLdap.java that simplify the code that addresses
timeout issues when connecting and searching referral LDAP databases, fixes the
getGroups() method to correctly get groups in referral LDAP databases, and does
code cleanup.
This first patch introduces 3 new LDAP settings that are derived from
metacat.properties:
1) ldapconnecttimelimit limits the time in milliseconds allowed for
LDAP server connections. This reduces the impact of any single
LDAP directory that may be unreachable (one of the referrals).
2) ldapsearchtimelimit limits the time in milliseconds allowed for
LDAP server searches. Again, servers with massive trees to search
might prove to be problematic, or servers that connect but do not
search correctly.
3) ldapsearchcountlimit limits the number of return entries allowed
for LDAP server searches. This is set pretty high (30000), but may
need to be altered when the KNB goes gold or platinum.
Also, this patch removes the run() method and the private GetGroups class,
and changes the AuthLdap class to not implement the Runnable interface.
These changes are in preparation for the next patch that will re-implement
the getGroups() method, removing the threaded timeout code.