Migración de una configuración XML de Waffle Spring Security a Spring Boot

Estoy tratando de usar la autenticación Waffle con Spring Security, de manera Spring Boot. El resultado esperado es "bloquear todo si la negociación falla".

El proyecto Waffle proporciona unejemplo de configuración para este tipo de caso de uso (en este ejemplo hay una alternativa a la autenticación HTTP simple si falla la negociación, que no necesito), suponiendo que la configuración se realice a través deweb.xml. Pero a pesar de muchos intentos, no entiendo cómo conectar Waffle con Spring Security usando Boot y la configuración solo de Java. Estoy usando Spring Boot 1.2.1.RELEASE con starters web y seguridad, la versión de Waffle es 1.7.3.

Me doy cuenta de que esta no es una pregunta específica, pero el foro de Spring ahora redirige aquí y los chicos de Waffle no saben sobre Spring Boot. ¿Podría alguien ayudarme a traducir una configuración de XML Spring Security a Spring Boot?

El primer paso es declarar una cadena de filtro y un oyente de cargador de contexto.

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/waffle-filter.xml</param-value> 
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Supongo (¿estoy equivocado?) Que esto ya está manejado por@EnableWebMvcSecurity, así que no hay nada que hacer aquí.

Lo siguiente es declarar un par de beans de proveedor, así que traduzco esto

<bean id="waffleWindowsAuthProvider" class="waffle.windows.auth.impl.WindowsAuthProviderImpl" />

<bean id="negotiateSecurityFilterProvider" class="waffle.servlet.spi.NegotiateSecurityFilterProvider">
    <constructor-arg ref="waffleWindowsAuthProvider" />
</bean>

<bean id="basicSecurityFilterProvider" class="waffle.servlet.spi.BasicSecurityFilterProvider">
    <constructor-arg ref="waffleWindowsAuthProvider" />
</bean>

<bean id="waffleSecurityFilterProviderCollection" class="waffle.servlet.spi.SecurityFilterProviderCollection">
    <constructor-arg>
        <list>
            <ref bean="negotiateSecurityFilterProvider" />               
            <ref bean="basicSecurityFilterProvider" />               
        </list>
    </constructor-arg>
</bean>

<bean id="waffleNegotiateSecurityFilter" class="waffle.spring.NegotiateSecurityFilter">
    <property name="Provider" ref="waffleSecurityFilterProviderCollection" />
</bean>

a esto

@Bean
public WindowsAuthProviderImpl waffleWindowsAuthProvider() {
    return new WindowsAuthProviderImpl();
}

@Bean
@Autowired
public NegotiateSecurityFilterProvider negotiateSecurityFilterProvider(final WindowsAuthProviderImpl windowsAuthProvider) {
    return new NegotiateSecurityFilterProvider(windowsAuthProvider);
}

@Bean
@Autowired
public BasicSecurityFilterProvider basicSecurityFilterProvider(final WindowsAuthProviderImpl windowsAuthProvider) {
    return new BasicSecurityFilterProvider(windowsAuthProvider);
}

@Bean
@Autowired
public SecurityFilterProviderCollection waffleSecurityFilterProviderCollection(final NegotiateSecurityFilterProvider negotiateSecurityFilterProvider, final BasicSecurityFilterProvider basicSecurityFilterProvider) {
    final SecurityFilterProvider[] securityFilterProviders = {
            negotiateSecurityFilterProvider,
            basicSecurityFilterProvider
    };
    return new SecurityFilterProviderCollection(securityFilterProviders);
}

@Bean
@Autowired
public NegotiateSecurityFilter waffleNegotiateSecurityFilter(final SecurityFilterProviderCollection securityFilterProviderCollection) {
    final NegotiateSecurityFilter negotiateSecurityFilter = new NegotiateSecurityFilter();
    negotiateSecurityFilter.setProvider(securityFilterProviderCollection);
    return negotiateSecurityFilter;
}

El paso final essec:http Configuración de la sección. Se declara un punto de entrada y el filtro se coloca antes del filtro de autenticación BÁSICO.

Ejemplo:

<sec:http entry-point-ref="negotiateSecurityFilterEntryPoint">
    <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
    <sec:custom-filter ref="waffleNegotiateSecurityFilter" position="BASIC_AUTH_FILTER" />
</sec:http>

<bean id="negotiateSecurityFilterEntryPoint" class="waffle.spring.NegotiateSecurityFilterEntryPoint">
    <property name="Provider" ref="waffleSecurityFilterProviderCollection" />
</bean>

Mi traducción de arranque:

@Autowired
private NegotiateSecurityFilterEntryPoint authenticationEntryPoint;

@Autowired
private NegotiateSecurityFilter negotiateSecurityFilter;    

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
            .authorizeRequests().anyRequest().authenticated()
            .and()
            .addFilterBefore(this.negotiateSecurityFilter, BasicAuthenticationFilter.class)
            .httpBasic().authenticationEntryPoint(this.authenticationEntryPoint);
}

@Bean
@Autowired
public NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint(final SecurityFilterProviderCollection securityFilterProviderCollection) {
    final NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint = new NegotiateSecurityFilterEntryPoint();
    negotiateSecurityFilterEntryPoint.setProvider(securityFilterProviderCollection);
    return negotiateSecurityFilterEntryPoint;
}

Ejecutar esta configuración conduce a un comportamiento extraño: a veces NTLM se activa y tiene éxito, a veces se negocia el filtro se bloquea con un error de "token no válido suministrado" (las mismas credenciales, usuario, navegador, configuración).

Ejemplo proporcionado funciona de maravilla, lo que me hace pensar que mi configuración de arranque está en cuestión.

Cualquier ayuda apreciada!

Respuestas a la pregunta(1)

Su respuesta a la pregunta