为啥 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 错误