2014-04-25 22 views
16

Sto scrivendo un'applicazione Web che richiede l'accesso da parte degli utenti. La mia azienda ha un server Active Directory che mi piacerebbe utilizzare per questo scopo. Tuttavia, sto riscontrando problemi nell'usare Spring per autenticare le credenziali degli utenti.Autenticazione directory attiva utilizzando Spring Security 3.2, Spring Ldap 2.0 e JavaConfig

Utilizzo Spring Security 3.2.2, Spring Ldap 2.0.1 e Java 1.7.

L'applicazione Web inizia bene, anche l'autenticazione contro l'autenticazione InMemory funziona bene, quindi il resto della mia applicazione sembra essere configurato correttamente.

Qui è la mia configurazione:

@Configuration 
@EnableWebSecurity 
public class LdapConfig extends WebSecurityConfigurerAdapter { 

    @Bean 
    public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() { 
     val provider = new ActiveDirectoryLdapAuthenticationProvider("my.domain", "ldap://LDAP_ID:389/OU=A_GROUP,DC=domain,DC=tld"); 
     provider.setConvertSubErrorCodesToExceptions(true); 
     provider.setUseAuthenticationRequestCredentials(true); 
     provider.setUseAuthenticationRequestCredentials(true); 
     return provider; 
    } 

    @Bean 
    public LoggerListener loggerListener() { 
     return new LoggerListener(); 
    } 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider()); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     // Configuration for Redirects, Login-Page and stuff 
    } 
} 

Quando provo ad effettuare il login utilizzando MY_USERNAME e MY_PASSWORD ottengo un Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials

completa Stacktrace:

14:59:00,508 DEBUG UsernamePasswordAuthenticationFilter:205 - Request is to process authentication 
14:59:00,509 DEBUG ProviderManager:152 - Authentication attempt using org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider 
14:59:00,509 DEBUG ActiveDirectoryLdapAuthenticationProvider:65 - Processing authentication request for user: USERNAME 
14:59:00,563 ERROR ActiveDirectoryLdapAuthenticationProvider:133 - Failed to locate directory entry for authenticated user: USERNAME 
javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-0310020A, problem 2001 (NO_OBJECT), data 0, best match of: 
    'OU=A_GROUP,DC=domain,DC=tld' 
    at com.sun.jndi.ldap.LdapCtx.mapErrorCode(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtx.searchAux(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtx.c_search(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtx.c_search(Unknown Source) 
    at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(Unknown Source) 
    at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(Unknown Source) 
    at javax.naming.directory.InitialDirContext.search(Unknown Source) 
    at org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleEntryInternal(SpringSecurityLdapTemplate.java:208) 
    at org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider.searchForUser(ActiveDirectoryLdapAuthenticationProvider.java:285) 
    at org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider.doAuthentication(ActiveDirectoryLdapAuthenticationProvider.java:130) 
    at org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:80) 
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156) 
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:177) 
    at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94) 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:211) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) 
    ... a few more 

14:59:00,597 WARN LoggerListener:60 - Authentication event AuthenticationFailureBadCredentialsEvent: USERNAME; details: org.sprin[email protected]0: RemoteIpAddUSERNAME: 0:0:0:0:0:0:0:1; SessionId: 1E9401031886F0155F0ACE881CC50A4B; exception: Bad credentials 
14:59:00,597 DEBUG UsernamePasswordAuthenticationFilter:348 - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials 
14:59:00,597 DEBUG UsernamePasswordAuthenticationFilter:349 - Updated SecurityContextHolder to contain null Authentication 
14:59:00,597 DEBUG UsernamePasswordAuthenticationFilter:350 - Delegating to authentication failure handler org.springframework.se[email protected]3d876453 

Quando si naviga AD utilizzando un Ldap-Explorer e cerca (&(objectClass=user)(userPrincipalName=MY_USERNAME)), che Spring fa in ActiveDirectoryLdapAuthenticationProvider: searchForUser (...), restituisce la corretta utente.

Quando si immette una password non valida, Spring restituisce ActiveDirectoryLdapAuthenticationProvider:200 - Active Directory authentication failed: Supplied password was invalid. Questo sembra essere OK.

È mancata una parte per la configurazione?

Esistono esempi funzionanti su come configurare Spring Ldap per un annuncio utilizzando JavaConfig? La guida ufficiale di primavera solo descrive il XML-Way http://docs.spring.io/spring-security/site/docs/3.1.5.RELEASE/reference/ldap.html#ldap-active-directory

Update: Appena aggiornato la mia AuthenticationProvider al seguente:

@Bean 
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() { 
    val provider = new ActiveDirectoryLdapAuthenticationProvider("company.tld", "ldap://LDAP_URL:389"); 
    provider.setConvertSubErrorCodesToExceptions(true); 
    provider.setUseAuthenticationRequestCredentials(true); 

    provider.setAuthoritiesMapper(myAuthoritiesMapper()); // see http://comdynamics.net/blog/544/spring-security-3-integration-with-active-directory-ldap/ 

    provider.setUseAuthenticationRequestCredentials(true); 

    return provider; 
} 

Funziona bene, grazie Guido!

Nota: gli stati molla indicano che un'eccezione PartialResultException viene ignorata. I Documenti dicono server (AD)

Alcuni di Active Directory non sono in grado di seguire automaticamente i rinvii, che spesso porta a un PartialResultException essere gettato nelle ricerche. È possibile specificare che PartialResultException deve essere ignorato impostando la proprietà ignorePartialResultException su true.

Forse c'è un modo per impostare questa proprietà con JavaConfig. L'ho appena ignorato.

+2

si può provare a rimuovere la 'UO = A_GROUP, DC = dominio, DC = tld' base dalla tua URL connessione? sembra che il fornitore primaverile di AD lo gestisca internamente. –

+0

Ho appena provato a rimuovere questa parte e funziona un po '. Console registra un errore di "Ignorare PartialResultException" e HTTP 403. – user3572914

+0

Il nome-login è il valore di 'sAMAccountName'.Potrebbe essere un problema anche questo? – user3572914

risposta