Spring ActiveDirectoryLdapAuthenticationProvider setSearchFilter方法

时间:2015-05-19 20:25:46

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

我有一个使用我的AD服务器的SpringFramework Security 4.0.0的工作设置。这对于默认搜索过滤器工作正常,直到我发现AD数据库中的用户比最初预期的扭曲得多。

我的设置如下,命名空间中的ActiveDirectoryLdapAuthenticationProvider bean:

<b:bean id="monFournisseurAD" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
    <b:constructor-arg value="subdom1.dom1.com" />
    <b:constructor-arg value="ldap://fsapps.company.uni:389/" />
    <b:constructor-arg value="dc=fsapps,dc=company,dc=uni" />
    <b:property name="searchFilter" value="(&amp;(userPrincipalName={0})(objectClass=user))" />
    <b:property name="userDetailsContextMapper">
        <b:bean class="org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper" />
    </b:property>
    <b:property name="authoritiesMapper" ref="grantedAuthoritiesMapper" />
    <b:property name="convertSubErrorCodesToExceptions" value="true" />
</b:bean>

然后我转移到以下设置,以删除对域的依赖:

<b:bean id="monFournisseurAD" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
    <b:constructor-arg value="" />
    <b:constructor-arg value="ldap://fsapps.company.uni:389/" />
    <b:constructor-arg value="dc=fsapps,dc=company,dc=uni" />
    <b:property name="searchFilter" value="(&amp;(sAMAccountName={0})(objectClass=user))" />
    <b:property name="userDetailsContextMapper">
        <b:bean class="org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper" />
    </b:property>
    <b:property name="authoritiesMapper" ref="grantedAuthoritiesMapper" />
    <b:property name="convertSubErrorCodesToExceptions" value="true" />
</b:bean>

现在问题是searchFilter中的{0}替换因此SpringFramework Security 4.0.0文档替换了username @ domain,其中domain似乎是AD服务器本身的默认域,在本例中是fsapps。 company.uni,因为我的第一个构造函数参数为空。 SpringFramework Security 4.0.0 Class ActiveDirectoryLdapAuthenticationProvider's documentation

问题:有没有办法只替换用户名而不是用户名@域?还有其他建议我如何规避这个问题吗?

注意:查看源代码后。似乎预期的行为应如下所示:如果ActiveDirectoryLdapAuthenticationProvider类的构造函数的domain参数是空字符串或全空格字符串,则将其设置为null。当域设置为null时,{0}模式的替换应该只是用户名而不添加域,这应该完全按照我的意愿执行:搜索sAMAccountName属性等于单独的用户名和objectClass用户的记录。那么,为什么它找不到作为域的rootDN中的用户(在我的例子中是第三个构造函数的参数fsapps.company.com)?我没有问题匹配具有以下形式的userPrincipalName的用户:username@fsapps.company.com而我无法使用以下形式的userPrincipalName匹配用户:username@whatever.domain?

注意2:我发现了问题,还没有找到解决方案。实际上,我的搜索过滤器非常好,Spring Security正确使用它。问题是通过绑定到AD服务器并绑定到服务器来执行身份验证我必须使用username@fsapps.company.com(如果已授权)或username@domain.in.constructor.arg.1。将根据具有域的用户名而不是没有域的用户名来检查sAMAccountName属性。如果添加了域,则没有sAMAccountName与作为参数传递的值匹配。

2 个答案:

答案 0 :(得分:0)

一个可行的解决方案是使用userPrincipalName依赖第一个显示的配置并清空第一个构造函数的参数,以将空字符串传递给构造函数。这样,任何内容都不会附加到用户名,而是输入简单的用户名,用户必须使用指定的域键入其完整的用户名。因此,使用username @ domain。

,而不是使用用户名登录

另一种解决方案是调查是否可以使用通用授权用户绑定到AD数据库,以代表其执行所有查询。我没有调查它是否可行(使用普通的LDAP完成)以及它需要多少努力。如果有人试验这个解决方案,最好在这里发布结果来分享这个解决方案。

答案 1 :(得分:0)

一种替代方法是基于this fix使用(sAMAccountName = {1})。