Spring Security múltiples proveedores de authentication exitosos

Quiero que los usuarios de mi aplicación web sean autenticados por LDAP Y authentication personalizada adicional. Es una aplicación Spring Boot escrita en Kotlin. He configurado AuthenticationManagerBuilder de la siguiente manera

@Autowinetworking lateinit var authenticationProvider: CustomAuthenticationProvider override fun configure(auth: AuthenticationManagerBuilder) { auth .authenticationProvider(authenticationProvider) auth .ldapAuthentication() .userDnPatterns("uid={0},ou=people") .groupSearchBase("ou=groups") .contextSource() .url("ldap://localhost:8389/dc=example,dc=com") .and() .passwordCompare() .passwordEncoder(PlaintextPasswordEncoder()) .passwordAttribute("userPassword") } 

Quiero encadenar la authentication para que, si el CustomAuthenticationProvider se autentica con éxito (la authentication de function no se ejecute), la authentication continúe utilizando el proveedor de authentication LDAP.

Tal como está escrito si CustomAuthenticationProvider se autentica correctamente, entonces la authentication LDAP (y cualquier otro proveedor de authentication posterior) no se evalúa. Solo si el CustomAuthenticationProvider arroja se realiza la authentication LDAP.

He leído varios artículos (por ejemplo, múltiples proveedores de authentication en Spring Security ) que detallan tener múltiples proveedores de authentication pero con comportamiento OR en lugar de comportamiento AND. ¿Alguna sugerencia?

Tal vez tengo algunos. Pero analicemos lo que sucede antes.

La implementación pnetworkingeterminada del administrador de authentication en Spring Security ( ProviderManager ) mantiene una list de proveedores de authentication y la primera que realiza una authentication exitosa detiene la cadena; el rest no se llama. Estoy seguro de que no puedes cambiar eso. Cuando utiliza AuthenticationManagerBuilder , agrega proveedores de authentication en ProviderManager .

En la image a continuación se muestra una descripción general de alto nivel de lo que está sucediendo:

Arquitectura de seguridad

En el código fuente esto se ve así (detalles salteados por brevedad):

 public Authentication authenticate(Authentication authentication) throws AuthenticationException { Class<? extends Authentication> toTest = authentication.getClass(); ... for (AuthenticationProvider provider : getProviders()) { if (!provider.supports(toTest)) { continue; } try { result = provider.authenticate(authentication); if (result != null) { ... break; } } ... catch (AuthenticationException e) { lastException = e; } } if (result != null) { ... return result; } } 

Entonces, ¿qué podrías hacer … hm. Primero, las preguntas de @dur son válidas 🙂 Segundo: es obvio que no puede hacer lo que quiera con el administrador de authentication estándar, lo cual tiene sentido para mí.

Lo que creo es que puedes probar dos cosas si aún quieres seguir así:

  1. Proporcione su propia implementación de administrador de authentication en su cadena de filters. Esto me parece un poco desafiante.
  2. Asegúrese de que su proveedor de authentication personalizado maneje todas las acciones de authentication necesarias.
  • Usar un object Kotlin en una class generada en time de ejecución
  • Cómo crear una consulta hql con left join usando el campo desde el object que se extiende
  • Error de la aplicación IBM Bluemix Cloud Foundry SpringBoot kotlin
  • Spring Boot: no puede include recurso estático
  • cómo usar annotations de spring como @Autowinetworking in kotlin?
  • ¿Debo usar @Repository cuando solo uso JdbcTemplate en mi class DAO?
  • Spring JPA no puede asignar un campo con un setter personalizado en una class de datos de Kotlin
  • Hibernate ignora el tipo de búsqueda 'vago' y carga las properties de inmediato
  • Validación de Java Bean en Spring MVC Controller PathVariables
  • ¿Cómo inyectar con IoC en las funciones de nivel superior de Kotlin? ¿Incluso uso contenedores de IoC?
  • JsonView en Spring + Kotlin