use of javax.naming.ldap.LdapName in project Openfire by igniterealtime.
the class LdapManagerTest method testGetProviderURL.
/**
* Test if {@link LdapManager#getProviderURL(LdapName)} generates a URL using basic attributes (happy-flow test).
*/
@Test
public void testGetProviderURL() throws Exception {
// Setup fixture.
final Map<String, String> properties = new HashMap<>();
properties.put("ldap.host", "localhost");
properties.put("ldap.port", "389");
final LdapManager manager = new LdapManager(properties);
final LdapName name = new LdapName("ou=people,dc=example,dc=org");
// Execute system under test.
final String result = manager.getProviderURL(name);
// Verify result.
assertEquals("ldaps://localhost:389/ou=people,dc=example,dc=org", result);
}
use of javax.naming.ldap.LdapName in project Openfire by igniterealtime.
the class LdapGroupProvider method processGroup.
private Group processGroup(LdapContext ctx, Attributes a, Set<String> membersToIgnore) throws NamingException {
XMPPServer server = XMPPServer.getInstance();
String serverName = server.getServerInfo().getXMPPDomain();
// Build `3 groups.
// group 1: uid=
// group 2: rest of the text until first comma
// group 3: rest of the text
Pattern pattern = Pattern.compile("(?i)(^" + manager.getUsernameField() + "=)([^,]+)(.+)");
// We have to process Active Directory differently.
boolean isAD = manager.getUsernameField().equals("sAMAccountName");
String[] returningAttributes = isAD ? new String[] { "distinguishedName", manager.getUsernameField() } : new String[] { manager.getUsernameField() };
SearchControls searchControls = new SearchControls();
searchControls.setReturningAttributes(returningAttributes);
// See if recursive searching is enabled. Otherwise, only search one level.
if (manager.isSubTreeSearch()) {
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
} else {
searchControls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
}
String name;
String description;
try {
name = ((String) ((a.get(manager.getGroupNameField())).get()));
} catch (Exception e) {
name = "";
}
try {
description = ((String) ((a.get(manager.getGroupDescriptionField())).get()));
} catch (Exception e) {
description = "";
}
Set<JID> members = new TreeSet<>();
Attribute memberField = a.get(manager.getGroupMemberField());
Log.debug("Loading members of group: {}", name);
if (memberField != null) {
NamingEnumeration ne = memberField.getAll();
while (ne.hasMore()) {
String username = (String) ne.next();
LdapName userDN = null;
// If not posix mode, each group member is stored as a full DN.
if (!manager.isPosixMode()) {
// Create an LDAP name with the full DN.
userDN = new LdapName(username);
try {
// Try to find the username with a regex pattern match.
Matcher matcher = pattern.matcher(username);
if (matcher.matches() && matcher.groupCount() == 3) {
// The username is in the DN, no additional search needed
username = matcher.group(2);
} else // The regex pattern match failed. This will happen if the
// the member DN's don't use the standard username field. For
// example, Active Directory has a username field of
// sAMAccountName, but stores group members as "CN=...".
{
// Turn the LDAP name into something we can use in a
// search by stripping off the comma.
StringBuilder userFilter = new StringBuilder();
userFilter.append("(&(");
userFilter.append(userDN.get(userDN.size() - 1));
userFilter.append(')');
userFilter.append(MessageFormat.format(manager.getSearchFilter(), "*"));
userFilter.append(')');
NamingEnumeration usrAnswer = ctx.search("", userFilter.toString(), searchControls);
if (usrAnswer.hasMoreElements()) {
SearchResult searchResult = null;
// Iterate through the entire set to find a matching distinguished name.
while (usrAnswer.hasMoreElements()) {
searchResult = (SearchResult) usrAnswer.nextElement();
Attributes attrs = searchResult.getAttributes();
if (isAD) {
Attribute userdnAttr = attrs.get("distinguishedName");
if (username.equals((String) userdnAttr.get())) {
// Exact match found, use it.
username = (String) attrs.get(manager.getUsernameField()).get();
break;
}
} else {
// No iteration occurs here, which is probably a bug.
username = (String) attrs.get(manager.getUsernameField()).get();
break;
}
}
}
// Close the enumeration.
usrAnswer.close();
}
} catch (Exception e) {
// TODO: A NPE is occuring here
Log.error(e.getMessage(), e);
}
}
// it passes the filter.
try {
if (!membersToIgnore.contains(username)) {
JID userJID;
int position = username.indexOf("@" + serverName);
// Create JID of local user if JID does not match a component's JID
if (position == -1) {
// In order to lookup a username from the manager, the username
// must be a properly escaped JID node.
String escapedUsername = JID.escapeNode(username);
// Check if escaped username is valid
userManager.getUser(escapedUsername);
// No exception, so the user must exist. Add the user as a group
// member using the escaped username.
userJID = server.createJID(escapedUsername, null);
} else {
// This is a JID of a component or node of a server's component
String node = username.substring(0, position);
String escapedUsername = JID.escapeNode(node);
userJID = new JID(escapedUsername + "@" + serverName);
}
members.add(userJID);
}
} catch (UserNotFoundException e) {
// not a user!
// maybe it is a group?
boolean isGroup = false;
if (manager.isFlattenNestedGroups()) {
if (manager.isPosixMode()) {
// in posix mode, the DN has not been set...
// Look up the userDN using the UID
String userDNStr = manager.retrieveSingle(null, "(" + manager.getUsernameField() + "=" + LdapManager.sanitizeSearchFilter(username) + ")", true);
if (userDNStr != null)
userDN = new LdapName(userDNStr);
}
if (userDN != null && manager.isGroupDN(userDN)) {
isGroup = true;
if (!membersToIgnore.contains(userDN.toString()) && !membersToIgnore.contains(username)) {
// prevent endless adding of cyclic referenced groups
membersToIgnore.add(username);
membersToIgnore.add(userDN.toString());
// it's a sub group not already added, so add its members
Log.debug("Adding members of sub-group: {}", userDN);
Group subGroup = getGroupByDN(userDN, membersToIgnore);
members.addAll(subGroup.getMembers());
}
}
}
if (!isGroup) {
// So, we want to simply ignore the user as a group member.
if (manager.isDebugEnabled()) {
Log.debug("LdapGroupProvider: User not found: " + username);
}
}
}
}
// Close the enumeration.
ne.close();
}
if (manager.isDebugEnabled()) {
Log.debug("LdapGroupProvider: Adding group \"" + name + "\" with " + members.size() + " members.");
}
Collection<JID> admins = Collections.emptyList();
return new Group(name, description, members, admins);
}
use of javax.naming.ldap.LdapName in project druid by druid-io.
the class LDAPCredentialsValidator method validateCredentials.
@Override
public AuthenticationResult validateCredentials(String authenticatorName, String authorizerName, String username, char[] password) {
SearchResult userResult;
LdapName userDn;
Map<String, Object> contextMap = new HashMap<>();
LdapUserPrincipal principal = this.cache.getOrExpire(username);
if (principal != null && principal.hasSameCredentials(password)) {
contextMap.put(BasicAuthUtils.SEARCH_RESULT_CONTEXT_KEY, principal.getSearchResult());
return new AuthenticationResult(username, authorizerName, authenticatorName, contextMap);
} else {
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
try {
// Set the context classloader same as the loader of this class so that BasicSecuritySSLSocketFactory
// class can be found
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
InitialDirContext dirContext = new InitialDirContext(bindProperties(this.ldapConfig));
try {
userResult = getLdapUserObject(this.ldapConfig, dirContext, username);
if (userResult == null) {
LOG.debug("User not found: %s", username);
return null;
}
userDn = new LdapName(userResult.getNameInNamespace());
} finally {
try {
dirContext.close();
} catch (Exception ignored) {
// ignored
}
}
} catch (NamingException e) {
LOG.error(e, "Exception during user lookup");
return null;
} finally {
Thread.currentThread().setContextClassLoader(currentClassLoader);
}
if (!validatePassword(this.ldapConfig, userDn, password)) {
LOG.debug("Password incorrect for LDAP user %s", username);
throw new BasicSecurityAuthenticationException("User LDAP authentication failed.");
}
byte[] salt = BasicAuthUtils.generateSalt();
byte[] hash = BasicAuthUtils.hashPassword(password, salt, this.ldapConfig.getCredentialIterations());
LdapUserPrincipal newPrincipal = new LdapUserPrincipal(username, new BasicAuthenticatorCredentials(salt, hash, this.ldapConfig.getCredentialIterations()), userResult);
this.cache.put(username, newPrincipal);
contextMap.put(BasicAuthUtils.SEARCH_RESULT_CONTEXT_KEY, userResult);
return new AuthenticationResult(username, authorizerName, authenticatorName, contextMap);
}
}
use of javax.naming.ldap.LdapName in project druid by druid-io.
the class LDAPRoleProvider method getRoles.
@Override
public Set<String> getRoles(String authorizerPrefix, AuthenticationResult authenticationResult) {
Set<String> roleNames = new HashSet<>();
Map<String, BasicAuthorizerGroupMapping> groupMappingMap = cacheManager.getGroupMappingMap(authorizerPrefix);
if (groupMappingMap == null) {
throw new IAE("Could not load groupMappingMap for authorizer [%s]", authorizerPrefix);
}
Map<String, BasicAuthorizerUser> userMap = cacheManager.getUserMap(authorizerPrefix);
if (userMap == null) {
throw new IAE("Could not load userMap for authorizer [%s]", authorizerPrefix);
}
// Get the groups assigned to the LDAP user
SearchResult searchResult = Optional.ofNullable(authenticationResult.getContext()).map(contextMap -> contextMap.get(BasicAuthUtils.SEARCH_RESULT_CONTEXT_KEY)).map(p -> {
if (p instanceof SearchResult) {
return (SearchResult) p;
} else {
return null;
}
}).orElse(null);
if (searchResult != null) {
try {
Set<LdapName> groupNamesFromLdap = getGroupsFromLdap(searchResult);
if (groupNamesFromLdap.isEmpty()) {
LOG.debug("User %s is not mapped to any groups", authenticationResult.getIdentity());
} else {
// Get the roles mapped to LDAP groups from the metastore.
// This allows us to authorize groups LDAP user belongs
roleNames.addAll(getRoles(groupMappingMap, groupNamesFromLdap));
}
} catch (NamingException e) {
LOG.error(e, "Exception in looking up groups for user %s", authenticationResult.getIdentity());
}
}
// Get the roles assigned to LDAP user from the metastore.
// This allow us to authorize LDAP users regardless of whether they belong to any groups or not in LDAP.
BasicAuthorizerUser user = userMap.get(authenticationResult.getIdentity());
if (user != null) {
roleNames.addAll(user.getRoles());
}
return roleNames;
}
use of javax.naming.ldap.LdapName in project druid by druid-io.
the class LDAPRoleProvider method getRoles.
@VisibleForTesting
public Set<String> getRoles(Map<String, BasicAuthorizerGroupMapping> groupMappingMap, Set<LdapName> groupNamesFromLdap) {
Set<String> roles = new HashSet<>();
if (groupMappingMap.size() == 0) {
return roles;
}
for (LdapName groupName : groupNamesFromLdap) {
for (Map.Entry<String, BasicAuthorizerGroupMapping> groupMappingEntry : groupMappingMap.entrySet()) {
BasicAuthorizerGroupMapping groupMapping = groupMappingEntry.getValue();
String mask = groupMapping.getGroupPattern();
try {
if (mask.startsWith("*,")) {
LdapName ln = new LdapName(mask.substring(2));
if (groupName.startsWith(ln)) {
roles.addAll(groupMapping.getRoles());
}
} else if (mask.endsWith(",*")) {
LdapName ln = new LdapName(mask.substring(0, mask.length() - 2));
if (groupName.endsWith(ln)) {
roles.addAll(groupMapping.getRoles());
}
} else {
LdapName ln = new LdapName(mask);
if (groupName.equals(ln)) {
roles.addAll(groupMapping.getRoles());
}
}
} catch (InvalidNameException e) {
throw new RuntimeException(String.format(Locale.getDefault(), "Configuration problem - Invalid groupMapping '%s'", mask));
}
}
}
return roles;
}
Aggregations