Spring ActiveDirectoryLdapAuthenticationProvider setSearchFilter 方法

Spring ActiveDirectoryLdapAuthenticationProvider setSearchFilter method

我的 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>

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

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

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

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

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

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

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