Home > database >  Spring Boot with XML based security configuration doesn't seem to use correct authentication ma
Spring Boot with XML based security configuration doesn't seem to use correct authentication ma

Time:09-23

We're trying to upgrade our old, mostly XML-based Spring web application, to Spring Boot (2.5.4). We've almost managed to do so but there's one thing that is still nagging us. Even after using Spring Boot we (still for now) have our Spring Security configuration defined like this in XML:

<http pattern="/api/something/v1/**" use-expressions="true" create-session="stateless" authentication-manager-ref="somethingAuthenticationManager">
    <http-basic/>

    <custom-filter ref="queryParamAuthFilter" before="BASIC_AUTH_FILTER" />

    <intercept-url pattern="/api/something/v1/**" access="hasRole('ROLE_SOMETHING')" />
    <csrf disabled="true"/>
</http>

The authentication managers are defined like this:

<authentication-manager alias="somethingAuthenticationManager">
    <authentication-provider user-service-ref="somethingUserDetailsService">
    </authentication-provider>
</authentication-manager>

<authentication-manager id="authenticationManager">
    <authentication-provider user-service-ref="customUserDetailsService">        
    </authentication-provider>
</authentication-manager>

The problem is that when I make a GET request to /api/something/v1 it seems like it's using the wrong authentication manager (the one with id authenticationManager) and not the somethingAuthenticationManager. This used to work before Spring Boot. Why is this and how can we resolve it?

Note that we're not using @EnableWebSecurity or any Java configuration related to Spring Security (afaik), everything is defined in our XML file.

Update

We start the application like this:

@EnableRabbit
@EnableRetry
@SpringBootApplication
@EnableAsync
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ImportResource(locations = {"classpath*:META-INF/spring/applicationContext*.xml", "classpath:spring/webflow-config.xml"})
public class OurApplication {

    public static void main(String[] args) {
        SpringApplication.run(OurApplication.class, args);
    }
}

which finds the WebappConfiguration that contains some additional configuration:

@Configuration
@ImportResource("classpath:spring/webmvc-config.xml")
public class WebappConfiguration implements WebMvcConfigurer {

@Bean
    public TilesConfigurer tilesConfigurer() {
        TilesConfigurer tilesConfigurer = new TilesConfigurer();
        String[] defs = {
                "classpath:WEB-INF/layouts/layouts.xml",
                "WEB-INF/views/**/views.xml"
        };
        // Scan views directory for Tiles configurations
        tilesConfigurer.setDefinitions(defs);
        return tilesConfigurer;
    }

    @Bean
    public TomcatServletWebServerFactory tomcatFactory() {
        return new TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                ((StandardJarScanner) context.getJarScanner()).setScanManifest(false);
                context.setResources(new ExtractingRoot());
            }
        };
    }

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainerCustomizer() {
        return container -> container.addContextCustomizers(context -> context.setReloadable(false));
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/web-resources/**").addResourceLocations("classpath:/META-INF/web-resources/");
    }

    @Bean
    public TilesViewResolver tilesViewResolver() {
        TilesViewResolver tilesViewResolver = new TilesViewResolver();
        tilesViewResolver.setRequestContextAttribute("requestContext");
        tilesViewResolver.setExposedContextBeanNames("ownerLogoUrlFinder");
        return tilesViewResolver;
    }

    @Bean
    public DispatcherServletRegistrationBean dispatcherServletRegistrationBean() {
        DispatcherServlet servlet = new DispatcherServlet();
        servlet.setApplicationContext(new AnnotationConfigWebApplicationContext());
        return new DispatcherServletRegistrationBean(servlet, "/");
    }

    @Bean
    public FilterRegistrationBean<OpenEntityManagerInViewFilter> openEntityManagerInViewFilterRegistrationBean(OpenEntityManagerInViewFilter openEntityManagerInViewFilter) {
        FilterRegistrationBean<OpenEntityManagerInViewFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(openEntityManagerInViewFilter);
        registration.addUrlPatterns("/*");
        registration.setName("openEntityManagerInViewFilter");
        registration.setOrder(1);
        return registration;
    }

    @Bean
    public OpenEntityManagerInViewFilter openEntityManagerInViewFilter() {
        return new OpenEntityManagerInViewFilter();
    }

}

Update 2

I get this when starting up:

2021-09-21 13:46:33.933  WARN 46673 --- [           main] o.s.b.f.parsing.FailFastProblemReporter  : Configuration problem: Overriding globally registered AuthenticationManager
Offending resource: file [/Users/johan/myproject/target/classes/META-INF/spring/applicationContext-security.xml]

CodePudding user response:

I have seen something similar and solved it by changing alias to id on my authentication-manager after reading this: https://github.com/spring-projects/spring-security/issues/2163

  • Related