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

Posted

技术标签:

【中文标题】试图将 ldap 连接到 spring 项目 - LDAP:错误代码 32 - 没有这样的对象【英文标题】:Trying to connect ldap to spring project - LDAP: error code 32 - No Such Object 【发布时间】:2013-01-25 18:38:09 【问题描述】:

我正在尝试在我的 Mac 上使用 openldap 启动并运行一个 spring 项目。

因为 openldap 是默认安装在 OSX 上的,所以我使用那个,然后用 Apache Directory studio 配置它。

我的目录如下所示:

还有这样的实体:

当我尝试使用 nilsi 和正确的密码登录时,我在 Eclipse 中遇到错误:

org.springframework.ldap.NameNotFoundException: [LDAP: error code 32 - No Such Object]; nested exception is javax.naming.NameNotFoundException: [LDAP: error code 32 - No Such Object]; remaining name ''
at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:174)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:306)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:259)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:606)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:524)
at org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleAttributeValues(SpringSecurityLdapTemplate.java:173)
at org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator.getGroupMembershipRoles(DefaultLdapAuthoritiesPopulator.java:215)
at org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator.getGrantedAuthorities(DefaultLdapAuthoritiesPopulator.java:185)
at org.springframework.security.ldap.authentication.LdapAuthenticationProvider.loadUserAuthorities(LdapAuthenticationProvider.java:197)
at org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:63)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:194)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)

在 ldap 控制台中我得到以下信息:

conn=1000 fd=14 ACCEPT from IP=127.0.0.1:49474 (IP=0.0.0.0:389)
connection_get(14): got connid=1000
connection_read(14): checking for input on id=1000
ber_get_next
ber_get_next: tag 0x30 len 34 contents:
op tag 0x60, time 1360507317
ber_get_next
conn=1000 op=0 do_bind
ber_scanf fmt (imt) ber:
ber_scanf fmt (m) ber:
>>> dnPrettyNormal: <ou=users,o=backlog>
<<< dnPrettyNormal: <ou=users,o=backlog>, <ou=users,o=backlog>
conn=1000 op=0 BIND dn="ou=users,o=backlog" method=128
do_bind: version=3 dn="ou=users,o=backlog" method=128
conn=1000 op=0 BIND dn="ou=users,o=backlog" mech=SIMPLE ssf=0
do_bind: v3 bind: "ou=users,o=backlog" to "ou=users,o=backlog"
send_ldap_result: conn=1000 op=0 p=3
send_ldap_response: msgid=1 tag=97 err=0
ber_flush2: 14 bytes to sd 14
conn=1000 op=0 RESULT tag=97 err=0 text=
connection_get(14): got connid=1000
connection_read(14): checking for input on id=1000
ber_get_next
ber_get_next: tag 0x30 len 85 contents:
op tag 0x63, time 1360507317
ber_get_next
conn=1000 op=1 do_search
ber_scanf fmt (miiiib) ber:
>>> dnPrettyNormal: <ou=users,o=backlog>
<<< dnPrettyNormal: <ou=users,o=backlog>, <ou=users,o=backlog>
ber_scanf fmt (mm) ber:
ber_scanf fmt (M) ber:
=> get_ctrls
ber_scanf fmt (m) ber:
=> get_ctrls: oid="2.16.840.1.113730.3.4.2" (noncritical)
<= get_ctrls: n=1 rc=0 err=""
conn=1000 op=1 SRCH base="ou=users,o=backlog" scope=2 deref=3 filter="(uid=nilsi)"
=> bdb_search
bdb_dn2entry("ou=users,o=backlog")
=> bdb_dn2id("o=backlog")
<= bdb_dn2id: got id=0x8
=> bdb_dn2id("ou=users,o=backlog")
<= bdb_dn2id: got id=0xa
entry_decode: "ou=users,o=backlog"
<= entry_decode(ou=users,o=backlog)
search_candidates: base="ou=users,o=backlog" (0x0000000a) scope=2
=> bdb_equality_candidates (objectClass)
=> key_read
<= bdb_index_read: failed (-30988)
<= bdb_equality_candidates: id=0, first=0, last=0
=> bdb_dn2idl("ou=users,o=backlog")
<= bdb_dn2idl: id=3 first=9 last=11
=> bdb_equality_candidates (uid)
<= bdb_equality_candidates: (uid) not indexed
bdb_search_candidates: id=-1 first=9 last=11
entry_decode: "cn=Knut Knutsson,ou=users,o=backlog"
<= entry_decode(cn=Knut Knutsson,ou=users,o=backlog)
=> bdb_dn2id("cn=knut knutsson,ou=users,o=backlog")
<= bdb_dn2id: got id=0x9
=> send_search_entry: conn 1000 dn="cn=Knut Knutsson,ou=users,o=backlog"
conn=1000 op=1 ENTRY dn="cn=knut knutsson,ou=users,o=backlog"
ber_flush2: 226 bytes to sd 14
<= send_search_entry: conn 1000 exit.
bdb_search: 10 does not match filter
entry_decode: "cn=Mathias Nordin,ou=users,o=backlog"
<= entry_decode(cn=Mathias Nordin,ou=users,o=backlog)
=> bdb_dn2id("cn=mathias nordin,ou=users,o=backlog")
<= bdb_dn2id: got id=0xb
bdb_search: 11 does not match filter
send_ldap_result: conn=1000 op=1 p=3
send_ldap_response: msgid=2 tag=101 err=0
ber_flush2: 14 bytes to sd 14
conn=1000 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
slap_listener_activate(8): 
>>> slap_listener(ldap:///)
conn=1001 fd=16 ACCEPT from IP=127.0.0.1:49475 (IP=0.0.0.0:389)
connection_get(16): got connid=1001
connection_read(16): checking for input on id=1001
ber_get_next
ber_get_next: tag 0x30 len 51 contents:
op tag 0x60, time 1360507317
ber_get_next
conn=1001 op=0 do_bind
ber_scanf fmt (imt) ber:
ber_scanf fmt (m) ber:
>>> dnPrettyNormal: <cn=Knut Knutsson,ou=users,o=backlog>
<<< dnPrettyNormal: <cn=Knut Knutsson,ou=users,o=backlog>, <cn=knut knutsson,ou=users,o=backlog>
conn=1001 op=0 BIND dn="cn=Knut Knutsson,ou=users,o=backlog" method=128
do_bind: version=3 dn="cn=Knut Knutsson,ou=users,o=backlog" method=128
bdb_dn2entry("cn=knut knutsson,ou=users,o=backlog")
conn=1001 op=0 BIND dn="cn=Knut Knutsson,ou=users,o=backlog" mech=SIMPLE ssf=0
do_bind: v3 bind: "cn=Knut Knutsson,ou=users,o=backlog" to "cn=Knut Knutsson,ou=users,o=backlog"
send_ldap_result: conn=1001 op=0 p=3
send_ldap_response: msgid=1 tag=97 err=0
ber_flush2: 14 bytes to sd 16
conn=1001 op=0 RESULT tag=97 err=0 text=
connection_get(16): got connid=1001
connection_read(16): checking for input on id=1001
ber_get_next
ber_get_next: tag 0x30 len 101 contents:
op tag 0x63, time 1360507317
ber_get_next
conn=1001 op=1 do_search
ber_scanf fmt (miiiib) ber:
>>> dnPrettyNormal: <cn=Knut Knutsson,ou=users,o=backlog>
<<< dnPrettyNormal: <cn=Knut Knutsson,ou=users,o=backlog>, <cn=knut knutsson,ou=users,o=backlog>
ber_scanf fmt (m) ber:
ber_scanf fmt (M) ber:
=> get_ctrls
ber_scanf fmt (m) ber:
=> get_ctrls: oid="2.16.840.1.113730.3.4.2" (noncritical)
<= get_ctrls: n=1 rc=0 err=""
conn=1001 op=1 SRCH base="cn=Knut Knutsson,ou=users,o=backlog" scope=0 deref=3 filter="(objectClass=*)"
==> limits_get: conn=1001 op=1 self="cn=knut knutsson,ou=users,o=backlog" this="cn=knut knutsson,ou=users,o=backlog"
=> bdb_search
bdb_dn2entry("cn=knut knutsson,ou=users,o=backlog")
=> send_search_entry: conn 1001 dn="cn=Knut Knutsson,ou=users,o=backlog"
conn=1001 op=1 ENTRY dn="cn=knut knutsson,ou=users,o=backlog"
ber_flush2: 226 bytes to sd 16
<= send_search_entry: conn 1001 exit.
send_ldap_result: conn=1001 op=1 p=3
send_ldap_response: msgid=2 tag=101 err=0
ber_flush2: 14 bytes to sd 16
conn=1001 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
connection_get(16): got connid=1001
connection_read(16): checking for input on id=1001
ber_get_next
ber_get_next: tag 0x30 len 34 contents:
op tag 0x42, time 1360507317
ber_get_next
ber_get_next on fd 16 failed errno=0 (Undefined error: 0)
conn=1001 op=2 do_unbind
conn=1001 op=2 UNBIND
connection_close: conn=1001 sd=16
conn=1001 fd=16 closed
connection_get(14): got connid=1000
connection_read(14): checking for input on id=1000
ber_get_next
ber_get_next: tag 0x30 len 245 contents:
op tag 0x63, time 1360507317
ber_get_next
conn=1000 op=2 do_search
ber_scanf fmt (miiiib) ber:
>>> dnPrettyNormal: <>
<<< dnPrettyNormal: <>, <>
ber_scanf fmt (mm) ber:
>>> nameUIDPretty: <cn=Knut Knutsson,ou=users,o=backlog>
>>> dnPretty: <cn=Knut Knutsson,ou=users,o=backlog>
<<< dnPretty: <cn=Knut Knutsson,ou=users,o=backlog>
<<< nameUIDPretty: <cn=Knut Knutsson,ou=users,o=backlog>
>>> dnNormalize: <cn=Knut Knutsson,ou=users,o=backlog>
<<< dnNormalize: <cn=knut knutsson,ou=users,o=backlog>
ber_scanf fmt (M) ber:
=> get_ctrls
ber_scanf fmt (m) ber:
=> get_ctrls: oid="2.16.840.1.113730.3.4.2" (noncritical)
<= get_ctrls: n=1 rc=0 err=""
conn=1000 op=2 SRCH base="" scope=2 deref=3 filter="(uniqueMember=cn=knut knutsson,ou=users,o=backlog)"
conn=1000 op=2 SRCH attr=cn objectClass javaSerializedData javaClassName javaFactory javaCodeBase javaReferenceAddress javaClassNames javaRemoteLocation
send_ldap_result: conn=1000 op=2 p=3
send_ldap_response: msgid=3 tag=101 err=32
ber_flush2: 14 bytes to sd 14
conn=1000 op=2 SEARCH RESULT tag=101 err=32 nentries=0 text=

我与 ldap 的连接如下:

<security:http auto-config="true" use-expressions="true">

    <security:intercept-url pattern="/auth/login"
        access="permitAll" />

    <security:form-login login-page="/auth/login"
        authentication-failure-url="/auth/login?error=true" />

    <security:logout invalidate-session="true"
        logout-success-url="/auth/login" logout-url="/auth/logout" />

</security:http>

<security:ldap-server url="$ldap.url"
    manager-dn="$ldap.managerdn" manager-password="$ldap.managerpassword" />

还有属性文件:

# Ldap server settings:
ldap.url=ldap://localhost:389
ldap.managerdn=ou=users,o=backlog
ldap.managerpassword=1234
ldap.user-search-filter=(uid=0)
ldap.user-search-base=ou=users,o=backlog

slapd.conf 中的 DBD 定义:

#######################################################################
# BDB database definitions
#######################################################################

database    bdb
suffix      "o=backlog" 
rootdn      "ou=users,o=backlog"
# Cleartext passwords, especially for the rootdn, should
# be avoid.  See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw      MD5gdyb21LQTcIANtvYMT7QVQ==
# The database directory MUST exist prior to running slapd AND 
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory   /private/var/db/openldap/backlog
# Indices to maintain
index   objectClass eq

但是,当我尝试使用我的 ldap 目录中不存在的帐户登录时,Spring 以干净的日志和无效的用户名/密码响应进行响应。

此外,如果 ldap 返回以前没有使用过应用程序的用户,应用程序将自动映射具有权限的用户。所以换句话说,如果 ldap 只是返回一个 id/用户名,那么它应该可以工作。

【问题讨论】:

您好,请问您找到这个问题的原因了吗?我有同样的问题,有时用户可以登录有时我得到 NameNotFound 异常 rootdn 的选择非常非常糟糕。它应该是一个在 DIT 中存在的条目,并且您应该在应用程序中使用它。该帐户用于 OpenLDAP 本身。您应该创建一个具有适当权限的管理员用户,并让应用程序使用该帐户进行身份验证。 【参考方案1】:

我刚刚遇到了这个问题。在可能的情况下,错误与身份验证管理器有关。我们的配置(对我们有用)是:

<security:authentication-manager>
            <security:ldap-authentication-provider
                    user-search-filter="(uid=0)"
                    group-search-filter="(uniqueMember=0)"
                    group-role-attribute="cn"
                    role-prefix="ROLE_">
            </security:ldap-authentication-provider>
    </security:authentication-manager>

      <security:ldap-server url="ldap://172.31.7.20:389/dc=gt,dc=local"/> 

在我们的例子中,我们不需要 ldap 服务器的 manager-dn 配置,因为我们只使用身份验证和授权,但我们不修改来自 LDAP 的条目。

我们使用 OpenLDAP 作为 LDAP 服务器,架构为 rfc2307bis

【讨论】:

以上是关于试图将 ldap 连接到 spring 项目 - LDAP:错误代码 32 - 没有这样的对象的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security LDAP 和记住我

将 JAAS 用于具有 Spring 安全性的 LDAP 密码

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

使用 Spring LDAP 在 Java 中进行身份验证

如何将 AD 组映射到用户角色 Spring Security LDAP

无法将mysql连接到spring boot项目