LDAP: Add configurable filters to LDAP group search and AD user search
This lets the user configure custom filters for group searches in LDAP, and user searches in AD changed configuration in this commit: group_search.group_search_dn -> group_search.base_dn group_search.subtree_search -> group_search.subtree added for LDAP: group_search.filter group_search.user_attribute added for AD: user_search.base_dn user_search.filter user_search.subtree This also changes group_search.subtree to be true by default. This fixes elastic/elasticsearch#567 and fixes elastic/elasticsearch#553 Original commit: elastic/x-pack-elasticsearch@8a1246aefd
This commit is contained in:
parent
f29cc62829
commit
79d4b1e208
|
@ -63,12 +63,12 @@ public class ActiveDirectoryConnection extends AbstractLdapConnection {
|
|||
groupsSearchCtls.setTimeLimit(timeoutMilliseconds);
|
||||
|
||||
ImmutableList.Builder<String> groups = ImmutableList.builder();
|
||||
try (ClosableNamingEnumeration groupsAnswer = new ClosableNamingEnumeration(
|
||||
try (ClosableNamingEnumeration<SearchResult> groupsAnswer = new ClosableNamingEnumeration<>(
|
||||
jndiContext.search(groupSearchDN, groupsSearchFilter, groupsSearchCtls))) {
|
||||
|
||||
//Loop through the search results
|
||||
while (groupsAnswer.hasMoreElements()) {
|
||||
SearchResult sr = (SearchResult) groupsAnswer.next();
|
||||
SearchResult sr = groupsAnswer.next();
|
||||
groups.add(sr.getNameInNamespace());
|
||||
}
|
||||
} catch (NamingException | LdapException ne) {
|
||||
|
@ -91,19 +91,19 @@ public class ActiveDirectoryConnection extends AbstractLdapConnection {
|
|||
String userSearchFilter = "(objectClass=user)";
|
||||
String userReturnedAtts[] = { "tokenGroups" };
|
||||
userSearchCtls.setReturningAttributes(userReturnedAtts);
|
||||
try (ClosableNamingEnumeration userAnswer = new ClosableNamingEnumeration(
|
||||
try (ClosableNamingEnumeration<SearchResult> userAnswer = new ClosableNamingEnumeration<>(
|
||||
jndiContext.search(authenticatedUserDn(), userSearchFilter, userSearchCtls))) {
|
||||
|
||||
//Loop through the search results
|
||||
while (userAnswer.hasMoreElements()) {
|
||||
|
||||
SearchResult sr = (SearchResult) userAnswer.next();
|
||||
SearchResult sr = userAnswer.next();
|
||||
Attributes attrs = sr.getAttributes();
|
||||
|
||||
if (attrs != null) {
|
||||
try (ClosableNamingEnumeration<? extends Attribute> ae = new ClosableNamingEnumeration<>(attrs.getAll())) {
|
||||
while (ae.hasMore() ) {
|
||||
Attribute attr = (Attribute) ae.next();
|
||||
Attribute attr = ae.next();
|
||||
for (NamingEnumeration e = attr.getAll(); e.hasMore(); ) {
|
||||
byte[] sid = (byte[]) e.next();
|
||||
groupsSearchFilter.append("(objectSid=");
|
||||
|
|
|
@ -34,12 +34,16 @@ import java.util.Hashtable;
|
|||
public class ActiveDirectoryConnectionFactory extends ConnectionFactory<ActiveDirectoryConnection> {
|
||||
|
||||
public static final String AD_DOMAIN_NAME_SETTING = "domain_name";
|
||||
public static final String AD_USER_SEARCH_BASEDN_SETTING = "user_search_dn";
|
||||
public static final String AD_USER_SEARCH_BASEDN_SETTING = "user_search.base_dn";
|
||||
public static final String AD_USER_SEARCH_FILTER_SETTING = "user_search.filter";
|
||||
public static final String AD_USER_SEARCH_SUBTREE_SETTING = "user_search.subtree";
|
||||
|
||||
private final ImmutableMap<String, Serializable> sharedLdapEnv;
|
||||
private final String userSearchDN;
|
||||
private final String domainName;
|
||||
private final String userSearchFilter;
|
||||
private final int timeoutMilliseconds;
|
||||
private final Boolean userSearchSubtree;
|
||||
|
||||
@Inject
|
||||
public ActiveDirectoryConnectionFactory(RealmConfig config) {
|
||||
|
@ -50,6 +54,8 @@ public class ActiveDirectoryConnectionFactory extends ConnectionFactory<ActiveDi
|
|||
throw new ShieldSettingsException("missing [" + AD_DOMAIN_NAME_SETTING + "] setting for active directory");
|
||||
}
|
||||
userSearchDN = settings.get(AD_USER_SEARCH_BASEDN_SETTING, buildDnFromDomain(domainName));
|
||||
userSearchFilter = settings.get(AD_USER_SEARCH_FILTER_SETTING, "(&(objectClass=user)(|(sAMAccountName={0})(userPrincipalName={0}@" + domainName + ")))");
|
||||
userSearchSubtree = settings.getAsBoolean(AD_USER_SEARCH_SUBTREE_SETTING, true);
|
||||
timeoutMilliseconds = (int) settings.getAsTime(TIMEOUT_LDAP_SETTING, TIMEOUT_DEFAULT).millis();
|
||||
String[] ldapUrls = settings.getAsArray(URLS_SETTING, new String[] { "ldaps://" + domainName + ":636" });
|
||||
|
||||
|
@ -74,7 +80,7 @@ public class ActiveDirectoryConnectionFactory extends ConnectionFactory<ActiveDi
|
|||
*/
|
||||
@Override
|
||||
public ActiveDirectoryConnection open(String userName, SecuredString password) {
|
||||
String userPrincipal = userName + "@" + this.domainName;
|
||||
String userPrincipal = userName + "@" + domainName;
|
||||
Hashtable<String, Serializable> ldapEnv = new Hashtable<>(this.sharedLdapEnv);
|
||||
ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
ldapEnv.put(Context.SECURITY_PRINCIPAL, userPrincipal);
|
||||
|
@ -84,12 +90,11 @@ public class ActiveDirectoryConnectionFactory extends ConnectionFactory<ActiveDi
|
|||
try {
|
||||
ctx = new InitialDirContext(ldapEnv);
|
||||
SearchControls searchCtls = new SearchControls();
|
||||
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
searchCtls.setSearchScope(userSearchSubtree ? SearchControls.SUBTREE_SCOPE : SearchControls.ONELEVEL_SCOPE);
|
||||
searchCtls.setReturningAttributes(Strings.EMPTY_ARRAY);
|
||||
searchCtls.setTimeLimit(timeoutMilliseconds);
|
||||
String searchFilter = "(&(objectClass=user)(|(sAMAccountName={0})(userPrincipalName={1})))";
|
||||
try (ClosableNamingEnumeration<SearchResult> results = new ClosableNamingEnumeration(
|
||||
ctx.search(userSearchDN, searchFilter, new Object[] { userName, userPrincipal }, searchCtls))) {
|
||||
try (ClosableNamingEnumeration<SearchResult> results = new ClosableNamingEnumeration<>(
|
||||
ctx.search(userSearchDN, userSearchFilter, new Object[] { userName }, searchCtls))) {
|
||||
|
||||
if(results.hasMore()){
|
||||
SearchResult entry = results.next();
|
||||
|
@ -98,11 +103,12 @@ public class ActiveDirectoryConnectionFactory extends ConnectionFactory<ActiveDi
|
|||
if (!results.hasMore()) {
|
||||
return new ActiveDirectoryConnection(connectionLogger, ctx, name, userSearchDN, timeoutMilliseconds);
|
||||
}
|
||||
ctx.close();
|
||||
throw new ActiveDirectoryException("search for user [" + userName + "] by principle name yielded multiple results");
|
||||
} else {
|
||||
ctx.close();
|
||||
throw new ActiveDirectoryException("search for user [" + userName + "] by principle name yielded no results");
|
||||
}
|
||||
|
||||
ctx.close();
|
||||
throw new ActiveDirectoryException("search for user [" + userName + "] by principle name yielded multiple results");
|
||||
}
|
||||
} catch (NamingException | LdapException e) {
|
||||
if (ctx != null) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
package org.elasticsearch.shield.authc.ldap;
|
||||
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.shield.authc.support.ldap.AbstractLdapConnection;
|
||||
|
@ -29,20 +30,25 @@ import java.util.List;
|
|||
*/
|
||||
public class LdapConnection extends AbstractLdapConnection {
|
||||
|
||||
private final String groupSearchDN;
|
||||
private final int timeoutMilliseconds;
|
||||
private final boolean isGroupSubTreeSearch;
|
||||
private final boolean isFindGroupsByAttribute;
|
||||
private final String groupSearchDN;
|
||||
private final String groupAttribute = "memberOf";
|
||||
private final int timeoutMilliseconds;
|
||||
private final String userAttributeForGroupMembership;
|
||||
private final String groupSearchFilter;
|
||||
|
||||
/**
|
||||
* This object is intended to be constructed by the LdapConnectionFactory
|
||||
*/
|
||||
LdapConnection(ESLogger logger, DirContext ctx, String boundName, boolean isFindGroupsByAttribute, boolean isGroupSubTreeSearch, String groupSearchDN, int timeoutMilliseconds) {
|
||||
super(logger, ctx, boundName);
|
||||
LdapConnection(ESLogger logger, DirContext ctx, String bindDN, int timeoutMilliseconds, boolean isFindGroupsByAttribute, boolean isGroupSubTreeSearch,
|
||||
@Nullable String groupSearchFilter, @Nullable String groupSearchDN, @Nullable String userAttributeForGroupMembership) {
|
||||
super(logger, ctx, bindDN);
|
||||
this.isGroupSubTreeSearch = isGroupSubTreeSearch;
|
||||
this.groupSearchFilter = groupSearchFilter;
|
||||
this.groupSearchDN = groupSearchDN;
|
||||
this.isFindGroupsByAttribute = isFindGroupsByAttribute;
|
||||
this.userAttributeForGroupMembership = userAttributeForGroupMembership;
|
||||
this.timeoutMilliseconds = timeoutMilliseconds;
|
||||
}
|
||||
|
||||
|
@ -53,7 +59,7 @@ public class LdapConnection extends AbstractLdapConnection {
|
|||
*/
|
||||
@Override
|
||||
public List<String> groups() {
|
||||
List<String> groups = isFindGroupsByAttribute ? getGroupsFromUserAttrs(bindDn) : getGroupsFromSearch(bindDn);
|
||||
List<String> groups = isFindGroupsByAttribute ? getGroupsFromUserAttrs() : getGroupsFromSearch();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("found groups [{}] for userDN [{}]", groups, this.bindDn);
|
||||
}
|
||||
|
@ -63,29 +69,26 @@ public class LdapConnection extends AbstractLdapConnection {
|
|||
/**
|
||||
* Fetches the groups of a user by doing a search. This could be abstracted out into a strategy class or through
|
||||
* an inherited class (with groups as the template method).
|
||||
*
|
||||
* @param userDn user fully distinguished name to fetch group membership for
|
||||
* @return fully distinguished names of the roles
|
||||
*/
|
||||
public List<String> getGroupsFromSearch(String userDn) {
|
||||
public List<String> getGroupsFromSearch() {
|
||||
String userIdentifier = userAttributeForGroupMembership == null ? bindDn : readUserAttribute(userAttributeForGroupMembership);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("user identifier for group lookup is [{}]", userIdentifier);
|
||||
}
|
||||
List<String> groups = new LinkedList<>();
|
||||
SearchControls search = new SearchControls();
|
||||
search.setReturningAttributes(Strings.EMPTY_ARRAY);
|
||||
search.setSearchScope(this.isGroupSubTreeSearch ? SearchControls.SUBTREE_SCOPE : SearchControls.ONELEVEL_SCOPE);
|
||||
search.setTimeLimit(timeoutMilliseconds);
|
||||
|
||||
//This could be made could be made configurable but it should cover all cases
|
||||
String filter = "(&" +
|
||||
"(|(objectclass=groupOfNames)(objectclass=groupOfUniqueNames)(objectclass=group)) " +
|
||||
"(|(uniqueMember={0})(member={0})))";
|
||||
|
||||
try (ClosableNamingEnumeration<SearchResult> results = new ClosableNamingEnumeration<>(
|
||||
jndiContext.search(groupSearchDN, filter, new Object[] { userDn }, search))) {
|
||||
jndiContext.search(groupSearchDN, groupSearchFilter, new Object[] {userIdentifier}, search))) {
|
||||
while (results.hasMoreElements()) {
|
||||
groups.add(results.next().getNameInNamespace());
|
||||
}
|
||||
} catch (NamingException | LdapException e ) {
|
||||
throw new LdapException("could not search for an LDAP group for user [" + userDn + "]", e);
|
||||
throw new LdapException("could not search for an LDAP group", bindDn, e);
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
@ -94,16 +97,15 @@ public class LdapConnection extends AbstractLdapConnection {
|
|||
* Fetches the groups from the user attributes (if supported). This method could later be abstracted out
|
||||
* into a strategy class
|
||||
*
|
||||
* @param userDn User fully distinguished name to fetch group membership from
|
||||
* @return list of groups the user is a member of.
|
||||
*/
|
||||
public List<String> getGroupsFromUserAttrs(String userDn) {
|
||||
public List<String> getGroupsFromUserAttrs() {
|
||||
List<String> groupDns = new LinkedList<>();
|
||||
try {
|
||||
Attributes results = jndiContext.getAttributes(userDn, new String[] { groupAttribute });
|
||||
Attributes results = jndiContext.getAttributes(bindDn, new String[] { groupAttribute });
|
||||
try (ClosableNamingEnumeration<? extends Attribute> ae = new ClosableNamingEnumeration<>(results.getAll())) {
|
||||
while (ae.hasMore()) {
|
||||
Attribute attr = (Attribute) ae.next();
|
||||
Attribute attr = ae.next();
|
||||
for (NamingEnumeration attrEnum = attr.getAll(); attrEnum.hasMore(); ) {
|
||||
Object val = attrEnum.next();
|
||||
if (val instanceof String) {
|
||||
|
@ -114,8 +116,23 @@ public class LdapConnection extends AbstractLdapConnection {
|
|||
}
|
||||
}
|
||||
} catch (NamingException | LdapException e) {
|
||||
throw new LdapException("could not look up group attributes for user [" + userDn + "]", e);
|
||||
throw new LdapException("could not look up group attributes for user", bindDn, e);
|
||||
}
|
||||
return groupDns;
|
||||
}
|
||||
|
||||
String readUserAttribute(String userAttribute) {
|
||||
try {
|
||||
Attributes results = jndiContext.getAttributes(bindDn, new String[]{userAttribute});
|
||||
Attribute attribute = results.get(userAttribute);
|
||||
if (results.size() == 0) {
|
||||
throw new LdapException("No results returned for attribute [" + userAttribute + "]", bindDn);
|
||||
}
|
||||
return (String) attribute.get();
|
||||
} catch (NamingException e) {
|
||||
throw new LdapException("Could not look attribute [" + userAttribute + "]", bindDn, e);
|
||||
} catch (ClassCastException e) {
|
||||
throw new LdapException("Returned ldap attribute [" + userAttribute + "] is not of type String", bindDn, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,8 +32,14 @@ import java.util.Hashtable;
|
|||
public class LdapConnectionFactory extends ConnectionFactory<LdapConnection> {
|
||||
|
||||
public static final String USER_DN_TEMPLATES_SETTING = "user_dn_templates";
|
||||
public static final String GROUP_SEARCH_SUBTREE_SETTING = "group_search.subtree_search";
|
||||
public static final String GROUP_SEARCH_BASEDN_SETTING = "group_search.group_search_dn";
|
||||
public static final String GROUP_SEARCH_SUBTREE_SETTING = "group_search.subtree";
|
||||
public static final String GROUP_SEARCH_BASEDN_SETTING = "group_search.base_dn";
|
||||
public static final String GROUP_SEARCH_FILTER_SETTING = "group_search.filter";
|
||||
public static final String GROUP_SEARCH_USER_ATTRIBUTE_SETTING = "group_search.user_attribute";
|
||||
|
||||
private static final String GROUP_SEARCH_DEFAULT_FILTER = "(&" +
|
||||
"(|(objectclass=groupOfNames)(objectclass=groupOfUniqueNames)(objectclass=group))" +
|
||||
"(|(uniqueMember={0})(member={0})))";
|
||||
|
||||
private final ImmutableMap<String, Serializable> sharedLdapEnv;
|
||||
private final String[] userDnTemplates;
|
||||
|
@ -41,6 +47,8 @@ public class LdapConnectionFactory extends ConnectionFactory<LdapConnection> {
|
|||
protected final boolean groupSubTreeSearch;
|
||||
protected final boolean findGroupsByAttribute;
|
||||
private final int timeoutMilliseconds;
|
||||
private final String groupFilter;
|
||||
private final String groupSearchUserAttribute;
|
||||
|
||||
@Inject()
|
||||
public LdapConnectionFactory(RealmConfig config) {
|
||||
|
@ -69,7 +77,10 @@ public class LdapConnectionFactory extends ConnectionFactory<LdapConnection> {
|
|||
sharedLdapEnv = builder.build();
|
||||
groupSearchDN = settings.get(GROUP_SEARCH_BASEDN_SETTING);
|
||||
findGroupsByAttribute = groupSearchDN == null;
|
||||
groupSubTreeSearch = settings.getAsBoolean(GROUP_SEARCH_SUBTREE_SETTING, false);
|
||||
groupSubTreeSearch = settings.getAsBoolean(GROUP_SEARCH_SUBTREE_SETTING, true);
|
||||
groupFilter = settings.get(GROUP_SEARCH_FILTER_SETTING, GROUP_SEARCH_DEFAULT_FILTER);
|
||||
groupSearchUserAttribute = settings.get(GROUP_SEARCH_FILTER_SETTING) == null ?
|
||||
null : settings.get(GROUP_SEARCH_USER_ATTRIBUTE_SETTING); //if filter isn't set we don't want to change from using the DN
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,7 +104,8 @@ public class LdapConnectionFactory extends ConnectionFactory<LdapConnection> {
|
|||
DirContext ctx = new InitialDirContext(ldapEnv);
|
||||
|
||||
//return the first good connection
|
||||
return new LdapConnection(connectionLogger, ctx, dn, findGroupsByAttribute, groupSubTreeSearch, groupSearchDN, timeoutMilliseconds);
|
||||
return new LdapConnection(connectionLogger, ctx, dn, timeoutMilliseconds, findGroupsByAttribute, groupSubTreeSearch,
|
||||
groupFilter, groupSearchDN, groupSearchUserAttribute);
|
||||
|
||||
} catch (NamingException e) {
|
||||
logger.warn("failed LDAP authentication with user template [{}] and DN [{}]", e, template, dn);
|
||||
|
|
|
@ -109,7 +109,7 @@ public class ActiveDirectoryFactoryTests extends ElasticsearchTestCase {
|
|||
}
|
||||
|
||||
@Test @SuppressWarnings("unchecked")
|
||||
public void testAdAuth_specificUserSearch() {
|
||||
public void testAuthenticate_specificUserSearch() {
|
||||
Settings settings = buildAdSettings(AD_LDAP_URL, AD_DOMAIN, "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com", false);
|
||||
RealmConfig config = new RealmConfig("ad-test", settings);
|
||||
ActiveDirectoryConnectionFactory connectionFactory = new ActiveDirectoryConnectionFactory(config);
|
||||
|
@ -130,7 +130,7 @@ public class ActiveDirectoryFactoryTests extends ElasticsearchTestCase {
|
|||
}
|
||||
|
||||
@Test @SuppressWarnings("unchecked")
|
||||
public void testAdUpnLogin() {
|
||||
public void testAuthenticate_UserPrincipalName() {
|
||||
Settings settings = buildAdSettings(AD_LDAP_URL, AD_DOMAIN, "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com", false);
|
||||
RealmConfig config = new RealmConfig("ad-test", settings);
|
||||
ActiveDirectoryConnectionFactory connectionFactory = new ActiveDirectoryConnectionFactory(config);
|
||||
|
@ -156,7 +156,26 @@ public class ActiveDirectoryFactoryTests extends ElasticsearchTestCase {
|
|||
}
|
||||
|
||||
@Test @SuppressWarnings("unchecked")
|
||||
public void testAD_standardLdapConnection(){
|
||||
public void testCustomUserFilter() {
|
||||
Settings settings = ImmutableSettings.builder()
|
||||
.put(buildAdSettings(AD_LDAP_URL, AD_DOMAIN, "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com", false))
|
||||
.put(ActiveDirectoryConnectionFactory.AD_USER_SEARCH_FILTER_SETTING, "(&(objectclass=user)(userPrincipalName={0}@ad.test.elasticsearch.com))")
|
||||
.build();
|
||||
RealmConfig config = new RealmConfig("ad-test", settings);
|
||||
ActiveDirectoryConnectionFactory connectionFactory = new ActiveDirectoryConnectionFactory(config);
|
||||
|
||||
//Login with the UserPrincipalName
|
||||
try (AbstractLdapConnection ldap = connectionFactory.open("erik.selvig", SecuredStringTests.build(PASSWORD))) {
|
||||
List<String> groups = ldap.groups();
|
||||
assertThat(groups, containsInAnyOrder(
|
||||
containsString("Geniuses"),
|
||||
containsString("Domain Users")));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test @SuppressWarnings("unchecked")
|
||||
public void testStandardLdapConnection(){
|
||||
String groupSearchBase = "DC=ad,DC=test,DC=elasticsearch,DC=com";
|
||||
String userTemplate = "CN={0},CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com";
|
||||
Settings settings = LdapTest.buildLdapSettings(AD_LDAP_URL, userTemplate, groupSearchBase, true, false);
|
||||
|
@ -165,8 +184,8 @@ public class ActiveDirectoryFactoryTests extends ElasticsearchTestCase {
|
|||
|
||||
String user = "Bruce Banner";
|
||||
try (LdapConnection ldap = connectionFactory.open(user, SecuredStringTests.build(PASSWORD))) {
|
||||
List<String> groups = ldap.getGroupsFromUserAttrs(ldap.authenticatedUserDn());
|
||||
List<String> groups2 = ldap.getGroupsFromSearch(ldap.authenticatedUserDn());
|
||||
List<String> groups = ldap.getGroupsFromUserAttrs();
|
||||
List<String> groups2 = ldap.getGroupsFromSearch();
|
||||
|
||||
assertThat(groups, containsInAnyOrder(
|
||||
containsString("Avengers"),
|
||||
|
@ -194,7 +213,7 @@ public class ActiveDirectoryFactoryTests extends ElasticsearchTestCase {
|
|||
}
|
||||
|
||||
@Test(expected = LdapException.class)
|
||||
public void testADStandardLdapHostnameVerification(){
|
||||
public void testStandardLdapHostnameVerification(){
|
||||
String groupSearchBase = "DC=ad,DC=test,DC=elasticsearch,DC=com";
|
||||
String userTemplate = "CN={0},CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com";
|
||||
Settings settings = LdapTest.buildLdapSettings(AD_LDAP_URL, userTemplate, groupSearchBase, true);
|
||||
|
|
|
@ -114,7 +114,7 @@ public class LdapConnectionTests extends LdapTest {
|
|||
SecuredString userPass = SecuredStringTests.build("pass");
|
||||
|
||||
try (LdapConnection ldap = ldapFac.open(user, userPass)) {
|
||||
List<String> groups = ldap.getGroupsFromSearch(ldap.authenticatedUserDn());
|
||||
List<String> groups = ldap.getGroupsFromSearch();
|
||||
assertThat(groups, contains("cn=HMS Lydia,ou=crews,ou=groups,o=sevenSeas"));
|
||||
}
|
||||
}
|
||||
|
@ -129,8 +129,29 @@ public class LdapConnectionTests extends LdapTest {
|
|||
|
||||
String user = "Horatio Hornblower";
|
||||
try (LdapConnection ldap = ldapFac.open(user, SecuredStringTests.build("pass"))) {
|
||||
List<String> groups = ldap.getGroupsFromSearch(ldap.authenticatedUserDn());
|
||||
List<String> groups = ldap.getGroupsFromSearch();
|
||||
assertThat(groups, contains("cn=HMS Lydia,ou=crews,ou=groups,o=sevenSeas"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserAttributeLookup() {
|
||||
String groupSearchBase = "ou=crews,ou=groups,o=sevenSeas";
|
||||
String userTemplate = "cn={0},ou=people,o=sevenSeas";
|
||||
RealmConfig config = new RealmConfig("ldap_realm", buildLdapSettings(ldapUrl(), userTemplate, groupSearchBase, false));
|
||||
LdapConnectionFactory ldapFac = new LdapConnectionFactory(config);
|
||||
|
||||
|
||||
String user = "Horatio Hornblower";
|
||||
try (LdapConnection ldap = ldapFac.open(user, SecuredStringTests.build("pass"))) {
|
||||
assertThat(ldap.readUserAttribute("mail"), is("hhornblo@royalnavy.mod.uk"));
|
||||
assertThat(ldap.readUserAttribute("uid"), is("hhornblo"));
|
||||
try {
|
||||
ldap.readUserAttribute("nonexistentAttribute");
|
||||
fail("reading a non existent attribute should throw an LDAPException");
|
||||
} catch (LdapException e) {
|
||||
assertThat(e.getMessage(), containsString("No results"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,6 +71,23 @@ public class OpenLdapTests extends ElasticsearchTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomFilter() {
|
||||
String groupSearchBase = "ou=people,dc=oldap,dc=test,dc=elasticsearch,dc=com";
|
||||
String userTemplate = "uid={0},ou=people,dc=oldap,dc=test,dc=elasticsearch,dc=com";
|
||||
Settings settings = ImmutableSettings.builder()
|
||||
.put(LdapConnectionTests.buildLdapSettings(OPEN_LDAP_URL, userTemplate,groupSearchBase, true, false))
|
||||
.put(LdapConnectionFactory.GROUP_SEARCH_FILTER_SETTING, "(&(objectclass=posixGroup)(memberUID={0}))")
|
||||
.put(LdapConnectionFactory.GROUP_SEARCH_USER_ATTRIBUTE_SETTING, "uid")
|
||||
.build();
|
||||
RealmConfig config = new RealmConfig("oldap-test", settings);
|
||||
LdapConnectionFactory connectionFactory = new LdapConnectionFactory(config);
|
||||
|
||||
try (LdapConnection ldap = connectionFactory.open("selvig", SecuredStringTests.build(PASSWORD))){
|
||||
assertThat(ldap.groups(), hasItem(containsString("Geniuses")));
|
||||
}
|
||||
}
|
||||
|
||||
@Test @LuceneTestCase.AwaitsFix(bugUrl = "https://github.com/elasticsearch/elasticsearch-shield/issues/499")
|
||||
public void testTcpTimeout() {
|
||||
String groupSearchBase = "ou=people,dc=oldap,dc=test,dc=elasticsearch,dc=com";
|
||||
|
|
Loading…
Reference in New Issue