簡體   English   中英

Spring Security LDAP 身份驗證用戶必須是 AD 組的成員

[英]Spring Security LDAP authentication user must be a member of an AD group

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

我可以完美地使用我的憑據登錄。 但是,我需要添加一個檢查,即 AD 用戶也必須屬於特定的 AD 組(即AD-this-is-a-specific-group )。 登錄時,如果用戶不屬於特定的 AD 組,則應返回登錄錯誤。

我已經搜索了幾個小時,似乎無法在WebSecurityConfigurerAdapter找到明確的方法來執行此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();
}

不確定這是否是最好的方法(就 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); 

我很抱歉在聚會上遲到了 5 年,但我在 Spring Boot 中實現的非常簡單的 LDAP 身份驗證遇到了完全相同的問題。

我只想要這個: - 這是正確的用戶名嗎? - 密碼正確嗎? - 如果是,該 usr 是否在 MYGROUP 組中?

所以我的配置方法現在看起來很小。 我在一個單獨的 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");
    }

順便說一句:該 url 不像Spring Boot 指南中提到的那樣工作,它只能像這樣工作,就像一行中的所有內容一樣:

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

順便說一句,對於遵循該指南的每個人:如果您連接到現有的 LDAP 服務器,則不需要所有這些“spring.ldap.embedded”應用程序屬性。

所以非常感謝你的幫助!

我會把它放在這里,因為我認為這是不覆蓋任何方法的更簡單的方法。

在用戶搜索過濾器(我將使用您的)中,如果它符合您的 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,僅登錄指定組中的用戶

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM