Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Flag to enable searching of LDAP groups on subtrees #8400

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
import java.io.IOException;
import java.net.ServerSocket;
import java.util.List;

import javax.naming.directory.SearchControls;
import static java.util.Collections.singleton;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
Expand All @@ -67,6 +67,8 @@ public void defaultConfiguration() {
assertThat(authoritiesPopulator).hasFieldOrPropertyWithValue("groupRoleAttribute", "cn");
assertThat(authoritiesPopulator).hasFieldOrPropertyWithValue("groupSearchBase", "");
assertThat(authoritiesPopulator).hasFieldOrPropertyWithValue("groupSearchFilter", "(uniqueMember={0})");
assertThat(authoritiesPopulator).extracting("searchControls").hasFieldOrPropertyWithValue("searchScope",
SearchControls.ONELEVEL_SCOPE);
assertThat(ReflectionTestUtils.getField(getAuthoritiesMapper(provider), "prefix")).isEqualTo("ROLE_");
}

Expand Down Expand Up @@ -124,6 +126,29 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:on
}

@Test
public void groupSubtreeSearchCustom() {
this.spring.register(GroupSubtreeSearchConfig.class).autowire();
LdapAuthenticationProvider provider = ldapProvider();

assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "searchControls"))
.extracting("searchScope").isEqualTo(SearchControls.SUBTREE_SCOPE);
}

@EnableWebSecurity
static class GroupSubtreeSearchConfig extends BaseLdapProviderConfig {
// @formatter:off
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.contextSource(contextSource())
.userDnPatterns("uid={0},ou=people")
.groupSearchFilter("ou=groupName")
.groupSearchSubtree(true);
}
// @formatter:on
}

@Test
public void rolePrefixCustom() {
this.spring.register(RolePrefixConfig.class).autowire();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.ldap.LdapAuthenticationProviderBuilderSecurityBuilderTests.BaseLdapProviderConfig;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.test.SpringTestRule;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.test.web.servlet.MockMvc;

Expand Down Expand Up @@ -70,6 +72,15 @@ public void authenticationManagerWhenPortZeroThenAuthenticates() throws Exceptio
.andExpect(authenticated().withUsername("bob"));
}

@Test
public void authenticationManagerWhenSearchSubtreeThenNestedGroupFound() throws Exception {
this.spring.register(GroupSubtreeSearchConfig.class).autowire();

this.mockMvc.perform(formLogin().user("ben").password("benspassword"))
.andExpect(authenticated().withUsername("ben").withAuthorities(
AuthorityUtils.createAuthorityList("ROLE_SUBMANAGERS", "ROLE_MANAGERS", "ROLE_DEVELOPERS")));
}

@EnableWebSecurity
static class MultiLdapAuthenticationProvidersConfig extends WebSecurityConfigurerAdapter {
// @formatter:off
Expand Down Expand Up @@ -121,4 +132,18 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
.port(0);
}
}

@EnableWebSecurity
static class GroupSubtreeSearchConfig extends BaseLdapProviderConfig {
// @formatter:off
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})")
.groupSearchSubtree(true)
.userDnPatterns("uid={0},ou=people");
}
// @formatter:on
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
extends SecurityConfigurerAdapter<AuthenticationManager, B> {
private String groupRoleAttribute = "cn";
private String groupSearchBase = "";
private boolean groupSearchSubtree = false;
private String groupSearchFilter = "(uniqueMember={0})";
private String rolePrefix = "ROLE_";
private String userSearchBase = ""; // only for search
Expand Down Expand Up @@ -130,6 +131,7 @@ private LdapAuthoritiesPopulator getLdapAuthoritiesPopulator() {
contextSource, groupSearchBase);
defaultAuthoritiesPopulator.setGroupRoleAttribute(groupRoleAttribute);
defaultAuthoritiesPopulator.setGroupSearchFilter(groupSearchFilter);
defaultAuthoritiesPopulator.setSearchSubtree(groupSearchSubtree);
defaultAuthoritiesPopulator.setRolePrefix(this.rolePrefix);

this.ldapAuthoritiesPopulator = defaultAuthoritiesPopulator;
Expand Down Expand Up @@ -320,6 +322,19 @@ public LdapAuthenticationProviderConfigurer<B> groupSearchBase(String groupSearc
return this;
}

/**
* If set to true, a subtree scope search will be performed for group membership. If false a
* single-level search is used.
*
* @param searchSubtree set to true to enable searching of the entire tree below the
* <tt>groupSearchBase</tt>.
* @return the {@link LdapAuthenticationProviderConfigurer} for further customizations
*/
public LdapAuthenticationProviderConfigurer<B> groupSearchSubtree(boolean groupSearchSubtree) {
this.groupSearchSubtree = groupSearchSubtree;
return this;
}

/**
* The LDAP filter to search for groups. Defaults to "(uniqueMember={0})". The
* substituted parameter is the DN of the user.
Expand Down