Spring Security LDAP身份验证用户必须是AD组的成员

时间:2016-07-12 02:57:15

标签: java spring-security spring-boot ldap spring-ldap

我按照以下方式配置了Spring Boot Security: https://spring.io/guides/gs/securing-web/

我能够完美地使用我的凭据登录。但是,我需要添加一个检查,即AD用户也必须属于特定的AD组(即 AD-this-a-specific-group )。 登录时,如果用户不属于特定的AD组,则应返回登录错误。

我现在一直在搜索几个小时,似乎无法在WebSecurityConfigurerAdapter中找到明确的方法,我是否正确使用auth.groupSearchFilter

这是我的代码:

@Configuration 
@EnableWebSecurity    
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
Environment env;

public LdapContextSource contextSource () {
    LdapContextSource contextSource= new LdapContextSource();

    contextSource.setUrl(env.getRequiredProperty("ldap.url"));
    contextSource.setBase(env.getRequiredProperty("ldap.baseDn"));
    contextSource.setUserDn(env.getRequiredProperty("ldap.bindDn"));
    contextSource.setPassword(env.getRequiredProperty("ldap.batchPassword"));
    contextSource.afterPropertiesSet();
    return contextSource;
}

@Override
protected void configure(AuthenticationManagerBuilder auth)
        throws Exception {
     auth.ldapAuthentication()
        .userSearchFilter("(cn={0})")           
        .groupSearchBase("OU=Account Groups,OU=ITS Security")
        .groupSearchFilter("(cn=AD-this-is-a-specific-group)") 
        .contextSource(contextSource()); 
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().anyRequest().fullyAuthenticated()
        .and()
        .formLogin();
}

3 个答案:

答案 0 :(得分:5)

不确定这是否是执行此操作的最佳方式(就Spring Security的生命周期而言),但基本上我提供了自己的DefaultLdapAuthoritiesPopulator,其中我只覆盖{{1 }}

首先,我上面有错getGroupMembershipRoles,应该是:

auth.groupSearchFilter

其次,我创建了一个带有重写方法的匿名类(调用super并检查角色列表中的成员资格):

    .groupSearchFilter("(member={0})") 

答案 1 :(得分:3)

我很抱歉这个晚会迟了5年但我在Spring Boot中实现了非常简单的LDAP身份验证时遇到了同样的问题。

我只想要这个: - 这是正确的用户名吗? - 这是正确的密码吗? - 如果是的话,是MYGROUP组中的usr吗?

所以我的配置方法现在看起来很小。我在一个单独的bean中添加了populator,只是意识到我需要在“auth.ldapAuthentication”中添加它,以便调用它。

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {

auth.ldapAuthentication()
        .userSearchFilter("uid={0}")
        .ldapAuthoritiesPopulator(ldapAuthoritiesPopulator())
        .groupSearchFilter("(member={0})") 
        .contextSource(contextSource());
}

@Bean
public LdapAuthoritiesPopulator ldapAuthoritiesPopulator() {

DefaultLdapAuthoritiesPopulator populi = new DefaultLdapAuthoritiesPopulator(contextSource(), "") {

    @Override
    public Set<GrantedAuthority> getGroupMembershipRoles(String userDn, String username) {
        Set<GrantedAuthority> groupMembershipRoles = super.getGroupMembershipRoles(userDn, username);

        boolean isMemberOfSpecificAdGroup = false;
        for (GrantedAuthority grantedAuthority : groupMembershipRoles) {

            if ("ROLE_MYGROUP".equals(grantedAuthority.toString())) {
                isMemberOfSpecificAdGroup = true;
                break;
            }
        }

        if (!isMemberOfSpecificAdGroup) {

            throw new BadCredentialsException("User must be a member of " + "ROLE_MYGROUP");
        }
        return groupMembershipRoles;
    }
};

    return populi;
}

@Bean
public DefaultSpringSecurityContextSource contextSource() {
    return new DefaultSpringSecurityContextSource("ldap://blabla-some-url:389/dc=something,dc=something,dc=ch");
    }

顺便说一句:网址没有像Spring Boot guide中提到的那样工作,它只能像这样工作,就像一行中的所有内容一样:

return new DefaultSpringSecurityContextSource("ldap://blabla-some-url:389/dc=something,dc=something,dc=ch");

顺便提一下,每个人都遵循该指南:如果连接到现有的LDAP服务器,则不需要所有这些“spring.ldap.embedded”应用程序属性。

非常感谢你的帮助!

答案 2 :(得分:1)

我将其放在此处,因为我认为这是不覆盖任何方法的更简单方法。

在用户搜索过滤器(我将使用您的过滤器)中,如果它与您的LDAP结构相对应,则添加以下内容

原文:

.userSearchFilter("(cn={0})") 

已修改为搜索角色:

.userSearchFilter("(&(cn={0})(memberOf=CN=MYGROUP,OU=GROUP,DC=com,DC=company)")

这会同时搜索用户和成员身份

在我的情况下,我必须这样做,因为我有3种可能的角色:

(&(cn={0})(|(group1)(group2)(group3)))

如您所见,它可以搜索用户和1个或更多角色

此问题的答案可信:Spring Security Ldap, log in only users in specified group