为什么Spring Security的BindAuthenticator需要用户的读权限?

时间:2010-05-14 03:12:17

标签: java spring active-directory ldap spring-security

我目前正在使用Spring Security 3.0实现/配置Java Web应用程序的LDAP身份验证。我使用Microsoft AD LDS作为LDAP服务器并选择了Spring的BindAuthenticator。 我发现只有经过身份验证的用户是分区的Readers角色的成员时,身份验证才有效。 BindAuthenticator尝试在身份验证后读取用户的属性,这在从目录服务检索权限的情况下似乎是合理的。

作为LDAP和AD的新手,当应用程序集成在现有AD结构中时,这是否可以接受? 可以微调给用户dns只读取自己属性的权限,而不是将它们添加到Reader组吗?

由于 托马斯


编辑2010年3月8日: 这是我最终做的事情: 我复制了Spring的BindAuthenticator(全班)并更改了方法bindWithDn(),如下所示。差异用 DIFF 标记。

private DirContextOperations bindWithDn(String userDn, String username, String password) {
    BaseLdapPathContextSource ctxSource = (BaseLdapPathContextSource) getContextSource();
    DistinguishedName fullDn = new DistinguishedName(userDn);
    fullDn.prepend(ctxSource.getBaseLdapPath());

    logger.debug("Attempting to bind as " + fullDn);

    DirContext ctx = null;
    try {
        ctx = getContextSource().getContext(fullDn.toString(), password);
        // Check for password policy control
        PasswordPolicyControl ppolicy = PasswordPolicyControlExtractor.extractControl(ctx);

        // *DIFF* Attributes attrs = ctx.getAttributes(userDn, getUserAttributes());

        DirContextAdapter result = new DirContextAdapter(null, new DistinguishedName(userDn),  // *DIFF*
                ctxSource.getBaseLdapPath());

        if (ppolicy != null) {
            result.setAttributeValue(ppolicy.getID(), ppolicy);
        }

        return result;
    } catch (NamingException e) {
        // This will be thrown if an invalid user name is used and the method may
        // be called multiple times to try different names, so we trap the exception
        // unless a subclass wishes to implement more specialized behaviour.
        if ((e instanceof org.springframework.ldap.AuthenticationException)
                || (e instanceof org.springframework.ldap.OperationNotSupportedException)) {
            handleBindException(userDn, username, e);
        } else {
            throw e;
        }
    // *DIFF* } catch (javax.naming.NamingException e) {
    // *DIFF*     throw LdapUtils.convertLdapException(e);
    } finally {
        LdapUtils.closeContext(ctx);
    }

    return null;
}

1 个答案:

答案 0 :(得分:1)

对我来说,感觉BindAuthenticator执行LDAP绑定“作为”经过身份验证的用户,并使用LDAP来填充用户详细信息对象。我猜测LDAP服务器要求用户有一个角色授权他们读取自己的属性。

您是否尝试将属性集(通过setUserAttributes)限制为仅少数几个属性。我认为在AD中你可以将RBAC放在单独的属性上,这样你就可以阅读一个具有'Reader'角色保护的属性和一些不受保护的属性。

您的其他选择是:

  • 按照您的建议更改LDAP服务器上的RBAC,但我没有处方。
  • 使用不同的身份验证方法,该方法执行绑定作为通用服务器主体并读取属性。您可能仍需要以用户身份绑定以检查其密码。