java – Nexus和LDAP – JNDI-在针对OpenLDAP Server对用户进行身份验证时出现问题

我正在使用Nexus存储库管理器(nexus.sonatype.org)和开源LDAP插件(code.google.com/p/nexus-ldap/),我收到一个错误,指出使用了错误的协议版本(详情如下) .所有插件都使用JNDI LDAP服务提供程序连接到我的LDAP服务器.如果查看nexus.log文件中的堆栈跟踪,则在JNDI LDAP实现中的上下文初始化期间会发生异常.所以我的猜测是,下面描述的问题不是由Nexus插件引起的,而是由于JNDI的误用或对LDAP身份验证的误解造成的.

任何关于如何导致错误的猜测或想法都非常感谢!

哪些步骤将重现该问题?

>将Nexus配置为使用OpenLDAP 1.2.x服务器使用LdapAuthenticatingRealm – 因此LDAP协议的版本2.
>尝试从OpenLDAP-Server列出用户并将其映射到Nexus配置UI中的角色 – 完美运行.
>现在尝试使用已成功映射到角色的LDAP用户登录或验证正在运行的Nexus实例.

什么是预期的输出?你看到了什么呢?

在尝试登录时,我收到错误消息“用户名,密码不正确或无权使用Nexus用户界面.请重试.”.在Nexus日志文件中,我看到当Sun的JNDI-LDAP实现(参见下面的日志文件中的堆栈跟踪)尝试使用给定信息初始化上下文以便针对LDAP服务器对用户进行身份验证时引发的异常.使用Nexus UI进行的用户查找以及在身份验证期间执行的查找工作正常(请参阅下面的日志文件).

CommunicationException中包含的错误消息(“[LDAP:错误代码2 – 不支持的版本]”)表示使用了错误的LDAP协议版本.我试图明确使用协议版本2,因为OpenLDAP版本1.2.7-30仅支持LDAP v2(企业环境 – 服务器版本不可协商).我这样做是通过检查你的源代码,添加行“env.put(”java.naming.ldap.version“,”2“);”到se.devoteam.nexus.ldap.NexusLdapContextFactory:52.没有改变.

在测试期间,我意识到在浏览Sun源代码时,javax.naming.ldap.InitialLdapContext.InitialLdapContext() – 方法所做的第一件事就是将ldap协议版本设置为“3”(javax.naming.ldap.InitialLdapContext:131 ).虽然Java6文档解释了我使用的属性(java.sun [dot] com / javase / 6 / docs / technotes / guides / jndi / jndi-ldap-gl.html#version),JNDI-tutorial提到了这个解决协议版本冲突的正确方法(java.sun [dot] com / products / jndi / tutorial / ldap / misc / version.html)我想知道:使用JNDI时是否有办法明确使用LDAP协议版本2作为LDAP服务提供商?

接下来,我尝试使用最新版本的OpenLDAP服务器(openldap2-2.3)作为LDAP协议版本3请求的代理,这些请求将它们委托给旧服务器.同样的问题,同样的例外.

附加信息

环境:Nexus Webapp部署在Tomcat 6.0.16上
Nexus版本:1.3.6
ldap-realm版本:0.4
JRE版本:JDK 1.6.0_14-b08
平台:虚拟环境
LDAP目录品牌:OpenLDAP 1.2.7和2.2.3

nexus.log的相关部分:

2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - o.s.j.r.PlexusSecur~          - Realm: 'org.sonatype.jsecurity.realms.XmlAuthenticatingRealm', caused: User 'testuser' cannot be retrieved.
org.jsecurity.authc.AccountException: User 'testuser' cannot be retrieved.
    at org.sonatype.jsecurity.realms.XmlAuthenticatingRealm.doGetAuthenticationInfo(XmlAuthenticatingRealm.java:68)
    at org.jsecurity.realm.AuthenticatingRealm.getAuthenticationInfo(AuthenticatingRealm.java:168)
    at org.sonatype.jsecurity.web.WebPlexusSecurity.getAuthenticationInfo(WebPlexusSecurity.java:185)
    at org.jsecurity.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(ModularRealmAuthenticator.java:186)
    at org.jsecurity.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:276)
    at org.jsecurity.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:141)
    at org.jsecurity.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:171)
    at org.jsecurity.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:312)
    at org.jsecurity.subject.DelegatingSubject.login(DelegatingSubject.java:237)
    at org.jsecurity.web.filter.authc.AuthenticatingFilter.executeLogin(AuthenticatingFilter.java:49)
    at org.sonatype.nexus.security.filter.authc.NexusHttpAuthenticationFilter.onAccessDenied(NexusHttpAuthenticationFilter.java:121)
    at org.jsecurity.web.filter.AccessControlFilter.onPreHandle(AccessControlFilter.java:145)
    at org.jsecurity.web.filter.PathMatchingFilter.preHandle(PathMatchingFilter.java:175)
    at org.jsecurity.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:129)
    at org.jsecurity.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:180)
    at org.jsecurity.web.servlet.FilterChainWrapper.doFilter(FilterChainWrapper.java:57)
    at org.jsecurity.web.servlet.JSecurityFilter.doFilterInternal(JSecurityFilter.java:382)
    at org.jsecurity.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:180)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
    at org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:419)
    at org.apache.coyote.ajp.AjpAprProtocol$AjpConnectionHandler.process(AjpAprProtocol.java:378)
    at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1509)
    at java.lang.Thread.run(Thread.java:619)
Caused by: org.sonatype.jsecurity.realms.tools.NoSuchUserException: User with id='testuser' not found!
    at org.sonatype.jsecurity.realms.tools.DefaultConfigurationManager.readUser(DefaultConfigurationManager.java:410)
    at org.sonatype.jsecurity.realms.tools.ResourceMergingConfigurationManager.readUser(ResourceMergingConfigurationManager.java:278)
    at org.sonatype.jsecurity.realms.XmlAuthenticatingRealm.doGetAuthenticationInfo(XmlAuthenticatingRealm.java:64)
    ... 29 more
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.LdapAuthent~          - Authenticating user 'testuser' through LDAP
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.LdapAuthent~          - LDAP user search filter: (&(objectClass=account)(uid={0}))
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.NexusLdapCo~          - LDAP security principal not set
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.NexusLdapCo~          - LDAP security credentials not set
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.NexusLdapCo~          - LDAP provider url(s): ldap://ldap:389
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.NexusLdapCo~          - LDAP initial context factory: com.sun.jndi.ldap.LdapCtxFactory
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.NexusLdapCo~          - LDAP security protocol: null
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.NexusLdapCo~          - LDAP security authentication: null
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.NexusLdapCo~          - LDAP search scope: subtree
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.LdapAuthent~          - User object found
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.LdapAuthent~          - LDAP authentication principal: uid=testuser, dc=corporation,dc=de
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.NexusLdapCo~          - LDAP provider url(s): ldap://ldap:389
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.NexusLdapCo~          - LDAP initial context factory: com.sun.jndi.ldap.LdapCtxFactory
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.NexusLdapCo~          - LDAP security protocol: null
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - s.d.n.l.NexusLdapCo~          - LDAP security authentication: null
2009-10-23 15:06:37 ERROR [ajp-8009-3     ] - o.j.r.l.AbstractLda~          - LDAP naming error while attempting to authenticate user.
javax.naming.CommunicationException: [LDAP: error code 2 - version not supported]
    at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3089)
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2987)
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2789)
    at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2703)
    at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:293)
    at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:175)
    at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:193)
    at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:136)
    at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:66)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
    at javax.naming.InitialContext.init(InitialContext.java:223)
    at javax.naming.ldap.InitialLdapContext.<init>(InitialLdapContext.java:134)
    at se.devoteam.nexus.ldap.NexusLdapContextFactory.getLdapContext(NexusLdapContextFactory.java:63)
    at se.devoteam.nexus.ldap.LdapAuthenticatingRealm.queryForAuthenticationInfo(LdapAuthenticatingRealm.java:139)
    at org.jsecurity.realm.ldap.AbstractLdapRealm.doGetAuthenticationInfo(AbstractLdapRealm.java:186)
    at org.jsecurity.realm.AuthenticatingRealm.getAuthenticationInfo(AuthenticatingRealm.java:168)
    at org.sonatype.jsecurity.web.WebPlexusSecurity.getAuthenticationInfo(WebPlexusSecurity.java:185)
    at org.jsecurity.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(ModularRealmAuthenticator.java:186)
    at org.jsecurity.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:276)
    at org.jsecurity.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:141)
    at org.jsecurity.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:171)
    at org.jsecurity.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:312)
    at org.jsecurity.subject.DelegatingSubject.login(DelegatingSubject.java:237)
    at org.jsecurity.web.filter.authc.AuthenticatingFilter.executeLogin(AuthenticatingFilter.java:49)
    at org.sonatype.nexus.security.filter.authc.NexusHttpAuthenticationFilter.onAccessDenied(NexusHttpAuthenticationFilter.java:121)
    at org.jsecurity.web.filter.AccessControlFilter.onPreHandle(AccessControlFilter.java:145)
    at org.jsecurity.web.filter.PathMatchingFilter.preHandle(PathMatchingFilter.java:175)
    at org.jsecurity.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:129)
    at org.jsecurity.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:180)
    at org.jsecurity.web.servlet.FilterChainWrapper.doFilter(FilterChainWrapper.java:57)
    at org.jsecurity.web.servlet.JSecurityFilter.doFilterInternal(JSecurityFilter.java:382)
    at org.jsecurity.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:180)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
    at org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:419)
    at org.apache.coyote.ajp.AjpAprProtocol$AjpConnectionHandler.process(AjpAprProtocol.java:378)
    at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1509)
    at java.lang.Thread.run(Thread.java:619)
2009-10-23 15:06:37 INFO  [ajp-8009-3     ] - o.s.n.s.f.a.NexusSe~          - Unable to authenticate user [testuser] from address/host [172.31.2.155/172.31.2.155]
2009-10-23 15:06:37 DEBUG [ajp-8009-3     ] - o.s.n.e.Authenticat~:default  - Notifying 1 EventListener about event org.sonatype.nexus.auth.NexusAuthenticationEvent fired (org.sonatype.nexus.auth.NexusAuthenticationEvent@d637d)

解决方法:

嗯……我不是LDAP专家,但根据Bug ID: 4908306 LDAP Provider version negotiation fails with OpenLDAP server (LDAP v2)

InitialLdapContext is used for LDAP v3 only. It adds methods to DirContext that
make sense only for v3. To use DirContext methods, use InitialDirContext.
InitialDirContext will do the appropriate v2/v3 negotiation.
The change was made in 1.4.1 to tighten up the implementation to match the spec
and also to avoid sending extraneous BINDs for v3.

实际上,我对上述评论和InitialLdapContext javadoc的理解是:

This class is the starting context for performing LDAPv3-style extended operations and controls.

InitialLdapContext类不能用于LDAP-v2,它在源代码中将java.naming.ldap.version环境属性显式设置为“3”.对于LDAP-v2,您必须使用InitialDirContext.

如果更改服务器不是一个选项,我想你必须修补http://code.google.com/p/nexus-ldap/

上一篇:Slickflow.NET 开源工作流引擎基础介绍(九) -- .NET Core2.0 版本实现介绍


下一篇:从Java应用程序连接LDAP服务器