Spring LdapAuthenticationProvider在AbstractContextSource.getReadOnlyContext处引发NullPointerException

Spring LdapAuthenticationProvider在AbstractContextSource.getReadOnlyContext处引发NullPointerException,spring,security,spring-security,ldap,Spring,Security,Spring Security,Ldap,我使用了xml文件中定义的Spring Security LDAP身份验证,它运行良好: 它看起来与您期望的第一个实现相同,但authenticate方法引发以下异常: java.lang.NullPointerException org.springframework.ldap.core.support.AbstractContextSource.getReadOnlyContext(AbstractContextSource.java:125) org.springframework.ld

我使用了xml文件中定义的Spring Security LDAP身份验证,它运行良好:

它看起来与您期望的第一个实现相同,但authenticate方法引发以下异常:

java.lang.NullPointerException
org.springframework.ldap.core.support.AbstractContextSource.getReadOnlyContext(AbstractContextSource.java:125)
org.springframework.ldap.core.LdapTemplate.executeReadOnly(LdapTemplate.java:792)
org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleEntry(SpringSecurityLdapTemplate.java:196)
org.springframework.security.ldap.search.FilterBasedLdapUserSearch.searchForUser(FilterBasedLdapUserSearch.java:116)
org.springframework.security.ldap.authentication.BindAuthenticator.authenticate(BindAuthenticator.java:90)
org.springframework.security.ldap.authentication.LdapAuthenticationProvider.doAuthentication(LdapAuthenticationProvider.java:178)
org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:61)
myapp.security.AppAuthenticationProvider.authenticate(AppAuthenticationProvider.java:69)
第一种情况下的日志如下所示:

[myapp] 2012-05-16 11:38:44,339 INFO  org.springframework.security.ldap.DefaultSpringSecurityContextSource -  URL 'ldap://mail.company.com', root DN is ''
[myapp] 2012-05-16 11:38:44,364 INFO  org.springframework.security.ldap.DefaultSpringSecurityContextSource -  URL 'ldap://mail.company.com', root DN is ''
[myapp] 2012-05-16 11:38:44,365 DEBUG org.springframework.ldap.core.support.AbstractContextSource - AuthenticationSource not set - using default implementation
[myapp] 2012-05-16 11:38:44,365 INFO  org.springframework.ldap.core.support.AbstractContextSource - Property 'userDn' not set - anonymous context will be used for read-write operations
[myapp] 2012-05-16 11:38:44,365 DEBUG org.springframework.ldap.core.support.AbstractContextSource - Using LDAP pooling.
[myapp] 2012-05-16 11:38:44,365 DEBUG org.springframework.ldap.core.support.AbstractContextSource - Trying provider Urls: ldap://mail.company.com
[myapp] 2012-05-16 11:38:44,369 INFO  org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator - groupSearchBase is empty. Searches will be performed from the context source base
[myapp] 2012-05-16 11:39:33,956 DEBUG org.springframework.security.authentication.ProviderManager - Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
[myapp] 2012-05-16 11:39:33,957 DEBUG org.springframework.security.ldap.authentication.LdapAuthenticationProvider - Processing authentication request for user: JohnDoe
[myapp] 2012-05-16 11:39:33,960 DEBUG org.springframework.security.ldap.search.FilterBasedLdapUserSearch - Searching for user 'JohnDoe', with user search [ searchFilter: '(uid={0})', searchBase: 'dc=company,dc=com', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
[myapp] 2012-05-16 11:39:34,812 DEBUG org.springframework.ldap.core.support.AbstractContextSource - Got Ldap context on server 'ldap://mail.company.com'
[myapp] 2012-05-16 11:39:35,025 DEBUG org.springframework.security.ldap.SpringSecurityLdapTemplate - Searching for entry under DN '', base = 'dc=company,dc=com', filter = '(uid={0})'
[myapp] 2012-05-16 11:39:35,060 DEBUG org.springframework.security.ldap.SpringSecurityLdapTemplate - Found DN: cn=JohnDoe,cn=users,dc=company,dc=com
[myapp] 2012-05-16 11:39:35,082 DEBUG org.springframework.security.ldap.authentication.BindAuthenticator - Attempting to bind as cn=JohnDoe,cn=users,dc=company,dc=com
在第二种情况下:

[myapp] 2012-05-16 11:34:13,563 INFO  org.springframework.security.ldap.DefaultSpringSecurityContextSource -  URL 'ldap://mail.company.com', root DN is ''
[myapp] 2012-05-16 11:34:28,363 INFO  org.springframework.security.ldap.DefaultSpringSecurityContextSource -  URL 'ldap://mail.company.com', root DN is ''
[myapp] 2012-05-16 11:34:37,194 DEBUG org.springframework.security.authentication.ProviderManager - Authentication attempt using myapp.security.AppAuthenticationProvider
[myapp] 2012-05-16 11:34:37,197 DEBUG org.springframework.security.ldap.authentication.LdapAuthenticationProvider - Processing authentication request for user: JohnDoe
[myapp] 2012-05-16 11:34:37,197 DEBUG org.springframework.security.ldap.search.FilterBasedLdapUserSearch - Searching for user 'JohnDoe', with user search [ searchFilter: '(uid={0})', searchBase: 'dc=company,dc=com', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]

有什么想法吗?

您没有完全初始化
DefaultSpringSecurityContextSource
(因为您是使用“新建”手动创建的)

将此项添加到创建下方,您应该已全部设置:

contextSource.afterPropertiesSet();
在这种情况下,这一行是关键:

[myapp] 2012-05-16 11:38:44,365 INFO  org.springframework.ldap.core.support.AbstractContextSource - Property 'userDn' not set - anonymous context will be used for read-write operations
当您尝试使用手动创建(但未正确初始化)的上下文源时,默认行为是使用非匿名访问进行只读操作。由于您没有指定任何管理器dn或密码,因此使用NPE失败


正确初始化实例(通过调用AfterPropertieSet())会将其设置为使用匿名访问进行只读,因为没有指定用户/pwd。

它可以工作!谢谢。我花了几个令人沮丧的小时,你又救了我几个;)SpringSecurityDocumentation或错误消息可以提供更实用的信息。在Grails3.2.9中使用SpringSecurityCore:3.1.2和SpringSecurityLDAP:3.0.2。出于某种原因,application.yml设置grails.plugin.springsecurity.ldap.context.anonymousReadOnly:true被忽略。AfterPropertieSet()修复了它。非常感谢。这是一个糟糕的API设计,NPE消息是误导性的,AfterPropertieSet方法是非直观的。我完全同意,这是一个非直观的糟糕API设计。谢谢。
[myapp] 2012-05-16 11:34:13,563 INFO  org.springframework.security.ldap.DefaultSpringSecurityContextSource -  URL 'ldap://mail.company.com', root DN is ''
[myapp] 2012-05-16 11:34:28,363 INFO  org.springframework.security.ldap.DefaultSpringSecurityContextSource -  URL 'ldap://mail.company.com', root DN is ''
[myapp] 2012-05-16 11:34:37,194 DEBUG org.springframework.security.authentication.ProviderManager - Authentication attempt using myapp.security.AppAuthenticationProvider
[myapp] 2012-05-16 11:34:37,197 DEBUG org.springframework.security.ldap.authentication.LdapAuthenticationProvider - Processing authentication request for user: JohnDoe
[myapp] 2012-05-16 11:34:37,197 DEBUG org.springframework.security.ldap.search.FilterBasedLdapUserSearch - Searching for user 'JohnDoe', with user search [ searchFilter: '(uid={0})', searchBase: 'dc=company,dc=com', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
contextSource.afterPropertiesSet();
[myapp] 2012-05-16 11:38:44,365 INFO  org.springframework.ldap.core.support.AbstractContextSource - Property 'userDn' not set - anonymous context will be used for read-write operations