使用 LDAP 和组成员身份的 Spring 安全性

Posted

技术标签:

【中文标题】使用 LDAP 和组成员身份的 Spring 安全性【英文标题】:Spring security using LDAP and group membership 【发布时间】:2018-11-29 19:27:13 【问题描述】:

我正在使用spring security来验证用户是否传入了有效的用户名和密码。

我还想验证用户是否属于特定组。

虽然凭据验证有效,但组成员身份验证无效。

我需要配置 ldapAuthoritiesPopulator 吗?

【问题讨论】:

【参考方案1】:

虽然凭据验证有效,但组成员身份验证无效。

我假设组成员身份是 ldap baseuserDn 的组合。

这里有一个代码可以帮助你。

    public class LDAPDetail
      private String url; //your LDAP url
      private Long timeout; // some timeout to connect LDAP
      private String domain; // domain of user
      private String userContainer; // typically value for OU=**,dc=**,dc=**
     // You should be getting value for _domain_ and _userContainer_ from user's LDAP detail                                 
    

    public void validateUserDetails()
       LdapDetail ldapDetail = //gets user's value which you want to validate.
       LdapTemplate ldapTemplate =  build(ldapDetail, "username", "password");

       AndFilter filter = new AndFilter();
            filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("cn", userName));

       ldapTemplate.authenticate(LdapUtils.emptyLdapName(), filter.toString(), "password")
    

    public static LdapTemplate build(LdapDetail ldapDetail, String userName, String password) 
            LdapContextSource ldapContextSource = new LdapContextSource();
            ldapContextSource.setBase(ldapDetail.getUserContainer());
            ldapContextSource.setUrl(ldapDetail.getUrl());
            ldapContextSource.setAnonymousReadOnly(true);
            ldapContextSource.setCacheEnvironmentProperties(false);
            ldapContextSource.setUserDn(ldapDetail.getDomain());
            ldapContextSource.setBaseEnvironmentProperties(buildContextFor(ldapDetail, userName, password));

            LdapTemplate ldapTemplate = new LdapTemplate(ldapContextSource);
            ldapTemplate.setContextSource(ldapContextSource);

            return ldapTemplate;
        

    public static Map<String, Object> buildContextFor(LdapDetail ldapDetail, String userName, String password) 
            Map<String, Object> env = new HashMap<>();

            env.put(Context.REFERRAL, "throw");
            env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
            env.put(Context.SECURITY_AUTHENTICATION, "simple");
            env.put(Context.SECURITY_PROTOCOL, "ssl");
            env.put("java.naming.factory.url.pkgs",
                    "org.jboss.naming:org.jnp.interfaces:org.jboss.naming:org.jnp.interfaces");
            env.put("com.sun.jndi.ldap.connect.timeout", String.valueOf(ldapDetail.getTimeout()));
            env.put(Context.PROVIDER_URL, ldapDetail.getUrl());
            env.put("ldap.domain", ldapDetail.getDomain());
            env.put(Context.SECURITY_PRINCIPAL, userName);
            env.put(Context.SECURITY_CREDENTIALS, password);

            return env;
   

【讨论】:

我没有看到群组验证。 已经在这里进行了用户验证.. filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("cn", userName));要添加组验证,请在上面添加以下代码(我尚未测试,但应该可以) filter.and(new EqualsFilter("objectclass", "group")).and(new EqualsFilter("cn", 组名)); 此外,今天我花时间在 LDAP 服务器上构建查询,该查询在特定组中的 user 上进行搜索,但无法进行。我跟着social.technet.microsoft.com/wiki/contents/articles/… 构造查询。你知道在组中搜索 user 的 ldap 查询吗?如果你有,那么我可以尝试在春天复制同样的内容。

以上是关于使用 LDAP 和组成员身份的 Spring 安全性的主要内容,如果未能解决你的问题,请参考以下文章

使用Spring Security从LDAP加载组

如何在 Spring 安全性中同时使用数据库和 LDAP 身份验证?

Grails - Spring 安全 ldap 活动目录身份验证 - 凭据错误错误

如何使用 xml 配置文件、JAVA、Spring 安全性对 LDAP 用户进行身份验证

具有Spring安全性的LDAP身份验证

Spring LDAP,检查指定组中用户的成员身份