【问题标题】:Spring Security LDAP authentication user must be a member of an AD groupSpring Security LDAP 认证用户必须是 AD 组的成员
【发布时间】:2016-11-14 03:08:04
【问题描述】:

我已经按照以下方式配置了 Spring Boot 安全性: https://spring.io/guides/gs/securing-web/

我可以完美地使用我的凭据登录。但是,我需要添加一项检查,确认 AD 用户也必须属于特定的 AD 组(即 AD-this-is-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();
}

【问题讨论】:

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


    【解决方案1】:

    我很抱歉迟到了 5 年,但我在 Spring Boot 中实现的非常简单的 LDAP 身份验证遇到了完全相同的问题。

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

    所以我的配置方法现在看起来非常小。我在一个单独的 bean 中添加了填充器,只是意识到我需要将它添加到“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”应用程序属性。

    非常感谢您的帮助!

    【讨论】:

    • 非常感谢您的评论。我对getGroupMembershipRoles 的调用总是返回一个大小为(0) 的列表。获得授权需要什么条件?
    • 就我在项目中看到的情况而言,唯一的要求是您的 LDAP 服务器需要具有与您在两个参数 userDn 和用户名中提供的完全相同的信息。因此 userDn 需要为用户提供完整的 Dn,并且此 Dn 和用户名必须存在于您的 LDAP 服务器中。实际上我意识到您可能需要在上面的示例中添加参数“groupSearchBase”-> 即“”。如果您愿意,可以在DefaultLdapAuthoritiesPopulator populi = new DefaultLdapAuthoritiesPopulator(contextSource(), groupSearchBase) { 行中添加 groupSearchBase
    【解决方案2】:

    不确定这是否是最好的方法(就 Spring Security 的生命周期而言),但基本上我提供了自己的 DefaultLdapAuthoritiesPopulator,我只覆盖了 getGroupMembershipRoles

    不过,第一件事,我上面的auth.groupSearchFilter 错了,应该是:

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

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

    auth
            .ldapAuthentication()
            .ldapAuthoritiesPopulator(new DefaultLdapAuthoritiesPopulator(contextSource, "OU=Account Groups,OU=ITS Security") {
    
                @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_AD-this-is-a-specific-group".equals(grantedAuthority.toString())) {                                                       
                            isMemberOfSpecificAdGroup = true;
                            break;
                        }
                    }
    
                    if (!isMemberOfSpecificAdGroup ) {
    
                        throw new BadCredentialsException("User must be a member of " + "AD-this-is-a-specific-group");
                    }
                    return groupMembershipRoles;
                }
            })
            .userSearchFilter("(cn={0})")           
            .groupSearchBase("OU=Account Groups,OU=ITS Security")
            .groupSearchFilter("(member={0})") 
            .contextSource(contextSource); 
    

    【讨论】:

      【解决方案3】:

      我将把它放在这里,因为我认为这是不覆盖任何方法的更简单的方法。

      在用户搜索过滤器(我将使用您的)中,如果它对应于您的 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

      【讨论】:

        猜你喜欢
        • 2016-08-11
        • 2021-11-10
        • 2012-10-15
        • 2015-03-04
        • 1970-01-01
        • 2015-10-06
        • 2012-09-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多