Spring LDAP Context.REFERRAL 跟随

Posted

技术标签:

【中文标题】Spring LDAP Context.REFERRAL 跟随【英文标题】:Spring LDAP Context.REFERRAL to follow 【发布时间】:2015-08-24 11:43:46 【问题描述】:

如何设置 LDAP Context.REFERRAL 以遵循 Spring Security 配置?这与我已经报告的一个问题有关,在发现我正在寻找的真正解决方案之前,我发现了一个不令人满意的解决方案,涉及在 LDAP 上下文中设置此环境属性以遵循 ActiveDirectoryLdapAuthenticationProvider 的引用。

这是对我原来问题的引用:Spring Security 4.0.0 + ActiveDirectoryLdapAuthenticationProvider + BadCredentialsException PartialResultException

附录:这里似乎没有人有这样的环境。尽管对这个问题保持沉默,但我在这里发布了我的配置,希望有人能够帮助我解决这个问题。我只是不知道我应该怎么做才能解决这个问题。

以下是我日志中的错误消息:

2015-06-15 10:32:19,810 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-1] /identite.proc at position 7 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2015-06-15 10:32:19,810 DEBUG (o.s.s.w.u.m.AntPathRequestMatcher.matches) [http-8443-1] Checking match of request : '/identite.proc'; against '/identite.proc'
2015-06-15 10:32:19,810 DEBUG (o.s.s.w.a.AbstractAuthenticationProcessingFilter.doFilter) [http-8443-1] Request is to process authentication
2015-06-15 10:32:19,811 DEBUG (o.s.s.a.ProviderManager.authenticate) [http-8443-1] Authentication attempt using org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider
2015-06-15 10:32:19,811 DEBUG (o.s.s.l.a.AbstractLdapAuthenticationProvider.authenticate) [http-8443-1] Processing authentication request for user: myusername
2015-06-15 10:32:19,841 DEBUG (o.s.s.l.SpringSecurityLdapTemplate.searchForSingleEntryInternal) [http-8443-1] Searching for entry under DN '', base = 'dc=dept,dc=company,dc=com', filter = '(&(userPrincipalName=0)(objectClass=user)(objectCategory=inetOrgPerson))'
2015-06-15 10:32:19,842 DEBUG (o.s.s.w.a.AbstractAuthenticationProcessingFilter.unsuccessfulAuthentication) [http-8443-1] Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
2015-06-15 10:32:19,842 DEBUG (o.s.s.w.a.AbstractAuthenticationProcessingFilter.unsuccessfulAuthentication) [http-8443-1] Updated SecurityContextHolder to contain null Authentication
2015-06-15 10:32:19,842 DEBUG (o.s.s.w.a.AbstractAuthenticationProcessingFilter.unsuccessfulAuthentication) [http-8443-1] Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@a5d7f2

这是配置:

<b:bean id="monFournisseurAD" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
    <b:constructor-arg value="dept.company.com" />
    <b:constructor-arg value="ldap://dept.company.com:3268/" />
    <b:constructor-arg value="dc=dept,dc=company,dc=com" />
    <b:property name="searchFilter" value="(&amp;(userPrincipalName=0)(objectClass=user)(objectCategory=inetOrgPerson))" />
    <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="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
    <b:constructor-arg value="ldap://dept.company.com:3268/dc=dept,dc=company,dc=com" />
    <b:property name="baseEnvironmentProperties">
        <b:map>
            <b:entry key="java.naming.referral" value="follow" />
        </b:map>
    </b:property>
</b:bean>

<b:bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
    <b:constructor-arg ref="contextSource" />
</b:bean>

<b:bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter" />
<b:bean id="myDeconnexionHandler" class="com.company.dept.web.my.DeconnexionHandler" />

ID 为 contextSource 和 ldapTemplate 的两个 bean 似乎没有改变任何东西。我试图让推荐遵循行为。这似乎不是配置它的正确方法。此外,这里 ldap URL 中的端口设置为 3268,因为它是通用目录,并且在其他地方的另一个描述中有人建议使用它。但是,结果与 389 端口完全相同。

如果我更改 bean monFournisseurAD 中的第一个构造函数参数以将其设置为单个 userPrincipalName 域,它将适用于该域中的所有用户。虽然我实际上可以使用 ldapsearch 命令从命令行对任何人进行身份验证,该命令使用 dept.company.com 而不是直接与用户关联的 userPrincipalName 域。事实上,如果我输入了错误的密码,我会得到具体的错误密码信息。这似乎证明了用户实际上是通过 AD/LDAP 进行身份验证的,但是 Spring 稍后无法获取该用户的属性。

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

最后,解决这个问题的唯一方法是修改代码,因为方法 org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider.searchForUser() 被连接到将 bindPrincipal 传递给 SpringSecurityLdapTemplate.searchForSingleEntryInternal()使用 XML 中定义的或使用 setSearchFilter() 设置的搜索过滤器实际为用户恢复记录。由于 bindPrincipal 实际上是 username@domain,所以这个值不适合在搜索过滤器中使用 sAMAccountName,它总是会失败。由于与 Active Directory 服务器的绑定是使用 userPrincipalName 和 bindPrincipal 执行的,因此您无法指定 searchForUser() 它必须仅在搜索中使用用户名,而不是 bindPrincipal (UPN)。我通过在我的包中复制整个类 org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider 并修改 searchForUser() 方法以将用户名而不是 bindPrincipal 传递给方法 searchForSingleEntryInternal() 来解决我的问题。这可行,但它仍然是有线/硬编码的解决方案。一个更优雅的解决方案是引入一个模式列表和一个方法来组合调用 searchForSingleEntryInternal() 的值,或者一个方法可以检测 searchFilter() 字符串所需的参数类型。

【讨论】:

以上是关于Spring LDAP Context.REFERRAL 跟随的主要内容,如果未能解决你的问题,请参考以下文章

Spring LDAP vs UnboundId LDAP

Spring-Ldap连接Ldap及简单的增删查改

Spring LDAP 不适用于 LDAP 模板

Spring 安全 ldap 连接管理

微软安全公告 ADV190023 的 Spring Ldap 影响(LDAP 通道绑定和 LDAP 签名)

试图将 ldap 连接到 spring 项目 - LDAP:错误代码 32 - 没有这样的对象