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.
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. –
Ho appena provato a rimuovere questa parte e funziona un po '. Console registra un errore di "Ignorare PartialResultException" e HTTP 403. – user3572914
Il nome-login è il valore di 'sAMAccountName'.Potrebbe essere un problema anche questo? – user3572914