2012-05-16 1 views
8

verwendete ich Spring Security LDAP-Authentifizierung in xml-Datei definiert und es funktionierte gut: LdapAuthenticationProvider wirft Nullpointer bei AbstractContextSource.getReadOnlyContext

<security:authentication-manager> 
    <security:ldap-authentication-provider 
     user-search-filter="(uid={0})" 
     user-search-base="dc=company,dc=com"> 
    </security:ldap-authentication-provider> 
</security:authentication-manager> 

<security:ldap-server url="ldap://mail.company.com" /> 

Ich brauchte eine gewisse Logik in Authenticator Anbieter einzufügen (in die Datenbank Protokollierung eines zu nennen) so implementiert ich DaoAuthenticationProvider LDAP zu verwenden:

xML-Konfiguration:

<security:authentication-manager> 
    <security:authentication-provider ref="appAuthenticationProvider" /> 
</security:authentication-manager> 

Klassenimplementierung:

@Service("appAuthenticationProvider") 
public class AppAuthenticationProvider extends DaoAuthenticationProvider { 

    private LdapAuthenticationProvider ldapProvider; 

    public AppAuthenticationProvider(){ 
     DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource("ldap://mail.company.com"); 
     BindAuthenticator authenticator = new BindAuthenticator(contextSource); 
     authenticator.setUserSearch(new FilterBasedLdapUserSearch("dc=company,dc=com", "(uid={0})", contextSource)); 
     ldapProvider = new LdapAuthenticationProvider(authenticator); 
    } 

    public Authentication authenticate(Authentication authRequest) throws AuthenticationException { 
     return ldapProvider.authenticate(authRequest); 
    } 

} 

Es sieht qute, was man von der ersten Implementierung erwarten würde, aber authentifizieren wirft Methode Ausnahme folgende:

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) 

Logs in ersten Fall sieht wie folgt aus:

[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 

Im zweiten Fall:

[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 ] 

Haben Sie eine Idee?

Antwort

18

Sie initialisieren die DefaultSpringSecurityContextSource nicht vollständig (da Sie sie manuell mit "neu" erstellen).

Fügen Sie diese unter der Schöpfung, und Sie sollten alle eingestellt werden:

contextSource.afterPropertiesSet(); 

In diesem speziellen Fall ist diese Linie der Schlüssel:

[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 

Wenn Sie versuchen, Ihre manuell erstellt verwenden (aber nicht richtig initialisiert) context source es geht um das Standardverhalten, das nicht-anonymen Zugriff auf schreibgeschützte Operationen verwendet. Da Sie ein Manager-DN/Kennwort angeben, schlägt es mit einer NPE fehl. Wenn Sie die Instanz ordnungsgemäß initialisieren (indem Sie afterPropertiesSet() aufrufen), wird sie so eingestellt, dass sie den anonymen Zugriff für schreibgeschützte Daten verwendet, da kein Benutzer/pwd angegeben ist.

+0

Es funktioniert! Danke vielmals. Ich habe ein paar frustrierende Stunden verbracht, Sie haben mir ein paar mehr gespart;) Spring Secuirty Dokumentation oder Fehlermeldungen könnten praktischere Informationen liefern. –

+0

Zwei Tage Arbeit, um diese Lösung zu finden Vielen Dank –

+0

Arbeitet in Grails 3.2.9 mit Feder-Sicherheit-Kern: 3.1.2 und Feder-Sicherheit-ldap: 3.0.2. Aus irgendeinem Grund wurde die Einstellung application.yml grails.plugin.springsecurity.ldap.context.anonymousReadOnly: true ignoriert. afterPropertiesSet() hat es behoben. –