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.
  • No puedo excluir MongoAutoConfiguration en Springboot-Kotlin (MongoSocketOpenException)
  • Referencias inyectadas de spring en Kotlin
  • Spring Boot @ Autoajustado con Kotlin en @Service siempre es nulo
  • Seguridad de spring. Página de inicio de session multilenguaje basada en url
  • Excepción lanzada al usar @Service en Kotlin
  • Spring MVC Error 404 Bad Request Kotlin
  • Usando @ EnableNeo4jRepositories (basePackageClasses = "myApp") en Kotlin
  • Probar los methods @Async de devolución de vacío de Testing
  • Las testings de Spring Boot no reutilizan el context
  • Kotlin no puede crear el campo @Autowinetworking en Class anotado con @Configuration @EnableWebMvc
  • El file spring-configuration-metadata.json no se genera en IntelliJ Idea for Kotlin @ConfigurationProperties class