Nexus и LDAP - JNDI-проблема при аутентификации пользователей на сервере OpenLDAP - PullRequest
4 голосов
/ 26 октября 2009

Я использую менеджер репозитория Nexus (nexus.sonatype.org) с плагином LDAP с открытым исходным кодом (code.google.com/p/nexus-ldap/) и получаю сообщение об ошибке, указывающее, что используется неверная версия протокола ( подробности ниже). Все, что делает плагин, использует поставщика услуг LDAP JNDI для подключения к моему серверу LDAP. Если вы посмотрите на трассировку стека в файле nexus.log, исключительная ситуация возникает во время инициализации контекста в реализации JNDI LDAP. Таким образом, я предполагаю, что проблема, описанная ниже, вызвана не плагином Nexus, а неправильным использованием JNDI или неправильным пониманием аутентификации LDAP.

Любая догадка или идея о том, как возникает эта ошибка, очень ценится!

Какие шаги воспроизведут проблему?

  1. Настройте Nexus для использования LdapAuthenticatingRealm с использованием сервера OpenLDAP 1.2.x - для этого версия 2 протокола LDAP.
  2. Попробуйте перечислить пользователей с OpenLDAP-сервера и сопоставить их с ролями в пользовательском интерфейсе конфигурации Nexus - отлично работает.
  3. Теперь попробуйте войти в систему или выполнить аутентификацию на работающем экземпляре Nexus, используя пользователя LDAP, который успешно сопоставлен с ролью.

Каков ожидаемый результат? Что вы видите вместо этого?

При попытке войти в систему я получаю сообщение об ошибке «Неверное имя пользователя, пароль или отсутствие разрешения на использование интерфейса пользователя Nexus. Попробуйте еще раз.». В файле журнала Nexus я вижу исключение, возникающее, когда реализация JNDI-LDAP от Sun (см. Трассировку стека, взятая из файла журнала ниже) пытается инициализировать контекст с заданной информацией для аутентификации пользователя на сервере 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 [точка] com / javase / 6 / docs / technotes / guides / jndi / jndi-ldap-gl.html # версия), которое я использовал, и в JNDI-руководстве упоминается это как правильный способ решения конфликтов версий протокола (java.sun [точка] com / products / jndi / tutorial / ldap / misc / version.html) Интересно: есть ли способ явно использовать версию 2 протокола LDAP при использовании JNDI как поставщик услуг 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)

1 Ответ

1 голос
/ 26 октября 2009

Мммм ... Я не эксперт LDAP, но, согласно Идентификатор ошибки: 4908306 Сбой согласования версии поставщика LDAP с сервером OpenLDAP (LDAP v2) :

InitialLdapContext используется только для LDAP v3. Он добавляет методы в DirContext, которые имеет смысл только для v3. Чтобы использовать методы DirContext, используйте InitialDirContext. InitialDirContext выполнит соответствующее согласование v2 / v3. Изменение было внесено в 1.4.1 для ужесточения реализации, чтобы соответствовать спецификации а также чтобы избежать отправки посторонних BIND для v3.

На самом деле, мое понимание вышеприведенного комментария и InitialLdapContext javadoc таково:

Этот класс является начальным контекстом для выполнения расширенных операций и элементов управления в стиле LDAPv3.

Класс InitialLdapContext нельзя использовать для LDAP-v2, он явно устанавливает свойство среды java.naming.ldap.version в "3" в своих источниках. Для LDAP-v2 вам придется использовать InitialDirContext.

Если смена сервера не возможна, думаю, вам придется патчить http://code.google.com/p/nexus-ldap/

...