java spring-security active-directory spring-ldap

Autenticación de Active Directory usando Spring Security 3.2, Spring Ldap 2.0 y JavaConfig



spring-security active-directory (1)

  1. Para PartialResultException Debe configurar la referencia de parámetros a "seguir" en su fuente de contexto.

Ej .: https://stackoverflow.com/a/26872236/2718510

Estoy escribiendo una aplicación web que requiere que los usuarios inicien sesión. Mi empresa tiene un servidor de Active Directory que me gustaría utilizar para este propósito. Sin embargo, estoy teniendo problemas para usar Spring para autenticar las credenciales de los usuarios.

Estoy usando Spring Security 3.2.2, Spring Ldap 2.0.1 y Java 1.7.

La aplicación web comienza bien, la autenticación contra la autenticación en memoria también funciona bien, por lo que el resto de mi aplicación parece estar configurado correctamente.

Aquí está mi configuración:

@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 } }

Cuando trato de iniciar sesión con MY_USERNAME y MY_PASSWORD, se produce un Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials

Stacktrace completo:

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.springframework.security.web.authentication.WebAuthenticationDetails@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.security.web.authentication.SimpleUrlAuthenticationFailureHandler@3d876453

Cuando navego por el AD usando un Ldap-Explorer y busco (&(objectClass=user)(userPrincipalName=MY_USERNAME)) , que Spring hace en ActiveDirectoryLdapAuthenticationProvider: searchForUser (...), devuelve el usuario correcto.

Al ingresar una contraseña no válida, Spring devuelve ActiveDirectoryLdapAuthenticationProvider:200 - Active Directory authentication failed: Supplied password was invalid . Esto parece estar bien.

¿Falta una pieza para la configuración?

¿Hay algún ejemplo práctico de cómo configurar Spring Ldap para un AD utilizando JavaConfig? La Guía de primavera oficial simplemente describe la forma XML http://docs.spring.io/spring-security/site/docs/3.1.5.RELEASE/reference/ldap.html#ldap-active-directory

Actualización: Acabo de actualizar mi AuthenticationProvider a lo siguiente:

@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; }

Funciona bien, gracias guido!

Nota: Estados de primavera, que se ignora una PartialResultException. Los docs dicen

Algunos servidores de Active Directory (AD) no pueden seguir automáticamente las referencias, lo que a menudo hace que se genere una PartialResultException en las búsquedas. Puede especificar que se omita PartialResultException estableciendo la propiedad ignorePartialResultException en true.

Tal vez haya una manera de establecer esta propiedad en JavaConfig, también. Simplemente lo ignoré.