AMQ-6148 re-using LDAP context for authentication

This commit is contained in:
Dmytro Chebotarskyi 2021-06-24 13:10:06 -07:00
parent 96a011d4b1
commit 610b87aed8
1 changed files with 44 additions and 52 deletions

View File

@ -73,7 +73,7 @@ public class LDAPLoginModule implements LoginModule {
private CallbackHandler handler; private CallbackHandler handler;
private LDAPLoginProperty [] config; private LDAPLoginProperty [] config;
private Principal user; private Principal user;
private Set<GroupPrincipal> groups = new HashSet<GroupPrincipal>(); private Set<GroupPrincipal> groups = new HashSet<>();
/** the authentication status*/ /** the authentication status*/
private boolean succeeded = false; private boolean succeeded = false;
@ -114,10 +114,8 @@ public class LDAPLoginModule implements LoginModule {
callbacks[1] = new PasswordCallback("Password", false); callbacks[1] = new PasswordCallback("Password", false);
try { try {
handler.handle(callbacks); handler.handle(callbacks);
} catch (IOException ioe) { } catch (IOException | UnsupportedCallbackException ioe) {
throw (LoginException)new LoginException().initCause(ioe); throw (LoginException)new LoginException().initCause(ioe);
} catch (UnsupportedCallbackException uce) {
throw (LoginException)new LoginException().initCause(uce);
} }
String password; String password;
@ -163,9 +161,7 @@ public class LDAPLoginModule implements LoginModule {
Set<Principal> principals = subject.getPrincipals(); Set<Principal> principals = subject.getPrincipals();
principals.add(user); principals.add(user);
for (GroupPrincipal gp : groups) { principals.addAll(groups);
principals.add(gp);
}
commitSucceeded = true; commitSucceeded = true;
return true; return true;
@ -175,7 +171,7 @@ public class LDAPLoginModule implements LoginModule {
public boolean abort() throws LoginException { public boolean abort() throws LoginException {
if (!succeeded) { if (!succeeded) {
return false; return false;
} else if (succeeded && commitSucceeded) { } else if (commitSucceeded) {
// we succeeded, but another required module failed // we succeeded, but another required module failed
logout(); logout();
} else { } else {
@ -187,11 +183,16 @@ public class LDAPLoginModule implements LoginModule {
return true; return true;
} }
protected void close(DirContext context) { protected void closeContext() {
if (context == null) {
return;
}
try { try {
context.close(); context.close();
} catch (Exception e) { } catch (Exception e) {
log.error(e.toString()); log.error(e.toString());
} finally {
context = null;
} }
} }
@ -200,13 +201,11 @@ public class LDAPLoginModule implements LoginModule {
MessageFormat userSearchMatchingFormat; MessageFormat userSearchMatchingFormat;
boolean userSearchSubtreeBool; boolean userSearchSubtreeBool;
DirContext context = null;
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Create the LDAP initial context."); log.debug("Create the LDAP initial context.");
} }
try { try {
context = open(); openContext();
} catch (NamingException ne) { } catch (NamingException ne) {
FailedLoginException ex = new FailedLoginException("Error opening LDAP connection"); FailedLoginException ex = new FailedLoginException("Error opening LDAP connection");
ex.initCause(ne); ex.initCause(ne);
@ -217,7 +216,7 @@ public class LDAPLoginModule implements LoginModule {
return false; return false;
userSearchMatchingFormat = new MessageFormat(getLDAPPropertyValue(USER_SEARCH_MATCHING)); userSearchMatchingFormat = new MessageFormat(getLDAPPropertyValue(USER_SEARCH_MATCHING));
userSearchSubtreeBool = Boolean.valueOf(getLDAPPropertyValue(USER_SEARCH_SUBTREE)).booleanValue(); userSearchSubtreeBool = Boolean.valueOf(getLDAPPropertyValue(USER_SEARCH_SUBTREE));
try { try {
@ -232,7 +231,7 @@ public class LDAPLoginModule implements LoginModule {
} }
// setup attributes // setup attributes
List<String> list = new ArrayList<String>(); List<String> list = new ArrayList<>();
if (isLoginPropertySet(USER_ROLE_NAME)) { if (isLoginPropertySet(USER_ROLE_NAME)) {
list.add(getLDAPPropertyValue(USER_ROLE_NAME)); list.add(getLDAPPropertyValue(USER_ROLE_NAME));
} }
@ -284,9 +283,7 @@ public class LDAPLoginModule implements LoginModule {
dn = path; dn = path;
} }
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
if (context != null) { closeContext();
close(context);
}
FailedLoginException ex = new FailedLoginException("Error parsing absolute name as URI."); FailedLoginException ex = new FailedLoginException("Error parsing absolute name as URI.");
ex.initCause(e); ex.initCause(e);
throw ex; throw ex;
@ -324,18 +321,12 @@ public class LDAPLoginModule implements LoginModule {
ex.initCause(e); ex.initCause(e);
throw ex; throw ex;
} catch (NamingException e) { } catch (NamingException e) {
if (context != null) {
close(context);
}
FailedLoginException ex = new FailedLoginException("Error contacting LDAP"); FailedLoginException ex = new FailedLoginException("Error contacting LDAP");
ex.initCause(e); ex.initCause(e);
throw ex; throw ex;
} finally {
closeContext();
} }
if (context != null) {
close(context);
}
return true; return true;
} }
@ -345,11 +336,11 @@ public class LDAPLoginModule implements LoginModule {
boolean roleSearchSubtreeBool; boolean roleSearchSubtreeBool;
boolean expandRolesBool; boolean expandRolesBool;
roleSearchMatchingFormat = new MessageFormat(getLDAPPropertyValue(ROLE_SEARCH_MATCHING)); roleSearchMatchingFormat = new MessageFormat(getLDAPPropertyValue(ROLE_SEARCH_MATCHING));
roleSearchSubtreeBool = Boolean.valueOf(getLDAPPropertyValue(ROLE_SEARCH_SUBTREE)).booleanValue(); roleSearchSubtreeBool = Boolean.parseBoolean(getLDAPPropertyValue(ROLE_SEARCH_SUBTREE));
expandRolesBool = Boolean.valueOf(getLDAPPropertyValue(EXPAND_ROLES)).booleanValue(); expandRolesBool = Boolean.parseBoolean(getLDAPPropertyValue(EXPAND_ROLES));
if (list == null) { if (list == null) {
list = new ArrayList<String>(); list = new ArrayList<>();
} }
if (!isLoginPropertySet(ROLE_NAME)) { if (!isLoginPropertySet(ROLE_NAME)) {
return list; return list;
@ -370,8 +361,8 @@ public class LDAPLoginModule implements LoginModule {
log.debug(" base DN: " + getLDAPPropertyValue(ROLE_BASE)); log.debug(" base DN: " + getLDAPPropertyValue(ROLE_BASE));
log.debug(" filter: " + filter); log.debug(" filter: " + filter);
} }
HashSet<String> haveSeenNames = new HashSet<String>(); HashSet<String> haveSeenNames = new HashSet<>();
Queue<String> pendingNameExpansion = new LinkedList<String>(); Queue<String> pendingNameExpansion = new LinkedList<>();
NamingEnumeration<SearchResult> results = context.search(getLDAPPropertyValue(ROLE_BASE), filter, constraints); NamingEnumeration<SearchResult> results = context.search(getLDAPPropertyValue(ROLE_BASE), filter, constraints);
while (results.hasMore()) { while (results.hasMore()) {
SearchResult result = results.next(); SearchResult result = results.next();
@ -436,7 +427,6 @@ public class LDAPLoginModule implements LoginModule {
protected boolean bindUser(DirContext context, String dn, String password) throws NamingException { protected boolean bindUser(DirContext context, String dn, String password) throws NamingException {
boolean isValid = false; boolean isValid = false;
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Binding the user."); log.debug("Binding the user.");
} }
@ -450,7 +440,6 @@ public class LDAPLoginModule implements LoginModule {
log.debug("User " + dn + " successfully bound."); log.debug("User " + dn + " successfully bound.");
} }
} catch (AuthenticationException e) { } catch (AuthenticationException e) {
isValid = false;
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Authentication failed for dn=" + dn); log.debug("Authentication failed for dn=" + dn);
} }
@ -476,7 +465,7 @@ public class LDAPLoginModule implements LoginModule {
return values; return values;
} }
if (values == null) { if (values == null) {
values = new ArrayList<String>(); values = new ArrayList<>();
} }
Attribute attr = attrs.get(attrId); Attribute attr = attrs.get(attrId);
if (attr == null) { if (attr == null) {
@ -490,9 +479,12 @@ public class LDAPLoginModule implements LoginModule {
return values; return values;
} }
protected DirContext open() throws NamingException { protected void openContext() throws NamingException {
if (context != null) {
return;
}
try { try {
Hashtable<String, String> env = new Hashtable<String, String>(); Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, getLDAPPropertyValue(INITIAL_CONTEXT_FACTORY)); env.put(Context.INITIAL_CONTEXT_FACTORY, getLDAPPropertyValue(INITIAL_CONTEXT_FACTORY));
if (isLoginPropertySet(CONNECTION_USERNAME)) { if (isLoginPropertySet(CONNECTION_USERNAME)) {
env.put(Context.SECURITY_PRINCIPAL, getLDAPPropertyValue(CONNECTION_USERNAME)); env.put(Context.SECURITY_PRINCIPAL, getLDAPPropertyValue(CONNECTION_USERNAME));
@ -511,22 +503,22 @@ public class LDAPLoginModule implements LoginModule {
context = new InitialDirContext(env); context = new InitialDirContext(env);
} catch (NamingException e) { } catch (NamingException e) {
closeContext();
log.error(e.toString()); log.error(e.toString());
throw e; throw e;
} }
return context;
} }
private String getLDAPPropertyValue (String propertyName){ private String getLDAPPropertyValue (String propertyName){
for (int i=0; i < config.length; i++ ) for (LDAPLoginProperty ldapLoginProperty : config)
if (config[i].getPropertyName() == propertyName) if (ldapLoginProperty.getPropertyName().equals(propertyName))
return config[i].getPropertyValue(); return ldapLoginProperty.getPropertyValue();
return null; return null;
} }
private boolean isLoginPropertySet(String propertyName) { private boolean isLoginPropertySet(String propertyName) {
for (int i=0; i < config.length; i++ ) { for (LDAPLoginProperty ldapLoginProperty : config) {
if (config[i].getPropertyName() == propertyName && (config[i].getPropertyValue() != null && !"".equals(config[i].getPropertyValue()))) if (ldapLoginProperty.getPropertyName().equals(propertyName) && (ldapLoginProperty.getPropertyValue() != null && !"".equals(ldapLoginProperty.getPropertyValue())))
return true; return true;
} }
return false; return false;