为啥 Spring Security 的 BindAuthenticator 需要用户读取权限?

Posted

技术标签:

【中文标题】为啥 Spring Security 的 BindAuthenticator 需要用户读取权限?【英文标题】:Why does Spring Security's BindAuthenticator require read permissions for users?为什么 Spring Security 的 BindAuthenticator 需要用户读取权限? 【发布时间】:2011-02-19 08:55:21 【问题描述】:

我目前正在使用 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;

【问题讨论】:

我选择的解决方案 - 几乎重复了 Spring Security 的 BindAuthenticator 并删除了读取用户属性的行。我正在使用自定义 AuthoritiesPopulator 所以那里没问题。 【参考方案1】:

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

您是否尝试将属性集(通过 setUserAttributes)限制为仅几个属性。我认为在 AD 中,您可以将 RBAC 放在单个属性上,因此您可能正在阅读一个具有“读者”角色保护的属性和其他一些不受保护的属性。

您的其他选择是:

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

【讨论】:

谢谢贾斯汀。我现在根本不查询任何属性。也已经考虑过创建一个不读取属性的自定义 BindAuthenticator,但在这样做之前,我感兴趣的是绑定用户读取自己的属性是否是一种常见行为。

以上是关于为啥 Spring Security 的 BindAuthenticator 需要用户读取权限?的主要内容,如果未能解决你的问题,请参考以下文章

尽管我们不提供 Spring Security 配置,为啥 Spring Security 应用程序会重定向到登录页面?

为啥spring-security-oauth oauth 2.0实现中需要scope参数

为啥 Spring Security 使用默认的预认证检查?

为啥 Spring Security 身份验证会导致 CORS 错误

Spring Security:为啥 Authentication 正在扩展 Principal?

为啥 Spring Security 的 BindAuthenticator 需要用户读取权限?