ARTEMIS-2535 Add ignorePartialResultException option to LDAPLoginModule
Active Directory servers are unable to handle referrals automatically. This causes a PartialResultException to be thrown if a referral is encountered beneath the base search DN, even if the LDAPLoginModule is set to ignore referrals. This option may be set to 'true' to ignore these exceptions, allowing login to proceed with the query results received before the exception was encountered. Note: there are no tests for this change as I could not reproduce the issue with the ApacheDS test server. The issue is specific to directory servers that don't support the ManageDsaIT control such as Active Directory.
This commit is contained in:
parent
c0ab83ef49
commit
d7d11a0c6f
|
@ -23,6 +23,7 @@ import javax.naming.Name;
|
|||
import javax.naming.NameParser;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.PartialResultException;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
@ -84,6 +85,7 @@ public class LDAPLoginModule implements LoginModule {
|
|||
private static final String SASL_LOGIN_CONFIG_SCOPE = "saslLoginConfigScope";
|
||||
private static final String AUTHENTICATE_USER = "authenticateUser";
|
||||
private static final String REFERRAL = "referral";
|
||||
private static final String IGNORE_PARTIAL_RESULT_EXCEPTION = "ignorePartialResultException";
|
||||
private static final String PASSWORD_CODEC = "passwordCodec";
|
||||
private static final String CONNECTION_POOL = "connectionPool";
|
||||
private static final String CONNECTION_TIMEOUT = "connectionTimeout";
|
||||
|
@ -131,6 +133,7 @@ public class LDAPLoginModule implements LoginModule {
|
|||
new LDAPLoginProperty(SASL_LOGIN_CONFIG_SCOPE, (String) options.get(SASL_LOGIN_CONFIG_SCOPE)),
|
||||
new LDAPLoginProperty(AUTHENTICATE_USER, (String) options.get(AUTHENTICATE_USER)),
|
||||
new LDAPLoginProperty(REFERRAL, (String) options.get(REFERRAL)),
|
||||
new LDAPLoginProperty(IGNORE_PARTIAL_RESULT_EXCEPTION, (String) options.get(IGNORE_PARTIAL_RESULT_EXCEPTION)),
|
||||
new LDAPLoginProperty(CONNECTION_POOL, (String) options.get(CONNECTION_POOL)),
|
||||
new LDAPLoginProperty(CONNECTION_TIMEOUT, (String) options.get(CONNECTION_TIMEOUT))};
|
||||
|
||||
|
@ -296,6 +299,7 @@ public class LDAPLoginModule implements LoginModule {
|
|||
|
||||
MessageFormat userSearchMatchingFormat;
|
||||
boolean userSearchSubtreeBool;
|
||||
boolean ignorePartialResultExceptionBool;
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Create the LDAP initial context.");
|
||||
|
@ -314,6 +318,7 @@ public class LDAPLoginModule implements LoginModule {
|
|||
|
||||
userSearchMatchingFormat = new MessageFormat(getLDAPPropertyValue(USER_SEARCH_MATCHING));
|
||||
userSearchSubtreeBool = Boolean.valueOf(getLDAPPropertyValue(USER_SEARCH_SUBTREE)).booleanValue();
|
||||
ignorePartialResultExceptionBool = Boolean.valueOf(getLDAPPropertyValue(IGNORE_PARTIAL_RESULT_EXCEPTION)).booleanValue();
|
||||
|
||||
try {
|
||||
|
||||
|
@ -357,8 +362,17 @@ public class LDAPLoginModule implements LoginModule {
|
|||
|
||||
SearchResult result = results.next();
|
||||
|
||||
if (results.hasMore()) {
|
||||
// ignore for now
|
||||
try {
|
||||
if (results.hasMore()) {
|
||||
// ignore for now
|
||||
}
|
||||
} catch (PartialResultException e) {
|
||||
// Workaround for AD servers not handling referrals correctly.
|
||||
if (ignorePartialResultExceptionBool) {
|
||||
logger.debug("PartialResultException encountered and ignored", e);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.isRelative()) {
|
||||
|
@ -447,9 +461,11 @@ public class LDAPLoginModule implements LoginModule {
|
|||
MessageFormat roleSearchMatchingFormat;
|
||||
boolean roleSearchSubtreeBool;
|
||||
boolean expandRolesBool;
|
||||
boolean ignorePartialResultExceptionBool;
|
||||
roleSearchMatchingFormat = new MessageFormat(getLDAPPropertyValue(ROLE_SEARCH_MATCHING));
|
||||
roleSearchSubtreeBool = Boolean.valueOf(getLDAPPropertyValue(ROLE_SEARCH_SUBTREE)).booleanValue();
|
||||
expandRolesBool = Boolean.valueOf(getLDAPPropertyValue(EXPAND_ROLES)).booleanValue();
|
||||
ignorePartialResultExceptionBool = Boolean.valueOf(getLDAPPropertyValue(IGNORE_PARTIAL_RESULT_EXCEPTION)).booleanValue();
|
||||
|
||||
final String filter = roleSearchMatchingFormat.format(new String[]{doRFC2254Encoding(dn), doRFC2254Encoding(username)});
|
||||
|
||||
|
@ -477,13 +493,22 @@ public class LDAPLoginModule implements LoginModule {
|
|||
throw ex;
|
||||
}
|
||||
|
||||
while (results.hasMore()) {
|
||||
SearchResult result = results.next();
|
||||
if (expandRolesBool) {
|
||||
haveSeenNames.add(result.getNameInNamespace());
|
||||
pendingNameExpansion.add(result.getNameInNamespace());
|
||||
try {
|
||||
while (results.hasMore()) {
|
||||
SearchResult result = results.next();
|
||||
if (expandRolesBool) {
|
||||
haveSeenNames.add(result.getNameInNamespace());
|
||||
pendingNameExpansion.add(result.getNameInNamespace());
|
||||
}
|
||||
addRoleAttribute(result, currentRoles);
|
||||
}
|
||||
} catch (PartialResultException e) {
|
||||
// Workaround for AD servers not handling referrals correctly.
|
||||
if (ignorePartialResultExceptionBool) {
|
||||
logger.debug("PartialResultException encountered and ignored", e);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
addRoleAttribute(result, currentRoles);
|
||||
}
|
||||
if (expandRolesBool) {
|
||||
MessageFormat expandRolesMatchingFormat = new MessageFormat(getLDAPPropertyValue(EXPAND_ROLES_MATCHING));
|
||||
|
@ -504,13 +529,22 @@ public class LDAPLoginModule implements LoginModule {
|
|||
ex.initCause(cause);
|
||||
throw ex;
|
||||
}
|
||||
while (results.hasMore()) {
|
||||
SearchResult result = results.next();
|
||||
name = result.getNameInNamespace();
|
||||
if (!haveSeenNames.contains(name)) {
|
||||
addRoleAttribute(result, currentRoles);
|
||||
haveSeenNames.add(name);
|
||||
pendingNameExpansion.add(name);
|
||||
try {
|
||||
while (results.hasMore()) {
|
||||
SearchResult result = results.next();
|
||||
name = result.getNameInNamespace();
|
||||
if (!haveSeenNames.contains(name)) {
|
||||
addRoleAttribute(result, currentRoles);
|
||||
haveSeenNames.add(name);
|
||||
pendingNameExpansion.add(name);
|
||||
}
|
||||
}
|
||||
} catch (PartialResultException e) {
|
||||
// Workaround for AD servers not handling referrals correctly.
|
||||
if (ignorePartialResultExceptionBool) {
|
||||
logger.debug("PartialResultException encountered and ignored", e);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -708,6 +708,12 @@ system. It is implemented by
|
|||
|
||||
- `referral` - specify how to handle referrals; valid values: `ignore`,
|
||||
`follow`, `throw`; default is `ignore`.
|
||||
|
||||
- `ignorePartialResultException` - boolean flag for use when searching Active
|
||||
Directory (AD). AD servers don't handle referrals automatically, which causes
|
||||
a `PartialResultException` to be thrown when referrals are encountered by a
|
||||
search, even if `referral` is set to `ignore`. Set to `true` to ignore these
|
||||
exceptions; default is `false`.
|
||||
|
||||
- `expandRoles` - boolean indicating whether to enable the role expansion
|
||||
functionality or not; default false. If enabled, then roles within roles will
|
||||
|
|
Loading…
Reference in New Issue