0

I am not using Spring Boot. I am using simply Spring MVC, Spring Security and Tomcat 10 As Server.

spring-webmvc: 6.0.3
spring-security-web & spring-security-config: 6.0.1

My Question is how my spring security config gets loaded into my Spring Web Application Context. As we do not explicitly load it. I have one class in classpath which only extends AbstractSecurityWebApplicationInitializer to initialize spring security filters. Below is my code for SpringSecurityConfigClass, MySecurityConfig class.

@Configuration
@EnableWebSecurity
public class MySecurityConfig {
    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetails() {
        UserDetails admin = User.builder()
                            .username("admin")
                            .password("{noop}admin")
                            .roles("ADMIN")
                            .build();
        return new InMemoryUserDetailsManager(admin);
    }
}

Now as we can see, SpringSecurityConfigClass, MySecurityConfig class is annotated with @Configuration and @EnableWebSecurity. Now as this is a Configuration where do we load it to our Spring Application Context/Web Application Context.

Now I know this is not a Spring Core Application, where we will load the Spring Configuration class into our Application Context using AnnotationConfigApplicationContext but in spring MVC also we do mention our Servlet config class. Below is my code for Servlet Configuration class, AppConfig class.

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.soumyadip.springSecurity")
public class AppConfig {
    @Bean
    public ViewResolver vieResolver() {
        InternalResourceViewResolver myViewResolver = new InternalResourceViewResolver();
        myViewResolver.setPrefix("/WEB-INF/views/");
        myViewResolver.setSuffix(".jsp");
        return myViewResolver;
    }

}

And here is my code for DispatcherServletConfigClass,

public class MyDispatcherServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer{

    @Override
    protected Class<?>[] getRootConfigClasses() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        // TODO Auto-generated method stub
        return new Class[] {AppConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        // TODO Auto-generated method stub
        return new String[] {"/"};
    }
    

}

Here as we can see there are two methods, getRootConfigClasses and getServletConfigClasses. And via getServletConfigClasses method we are returing our ServletConfiguration class. And this code works as expected, i.e. I am needing to input the password and user name.

As per the answer.

Spring's ApplicationContext provides the capability of loading multiple (hierarchical) contexts

Basically there can be two WebApplicationContext that gets loaded into Spring ApplicationContext in a hierarchy.

  1. Servlet WebApplicationContext where Servlet Specific configuration such as Controllers get loaded, the configuration class for this context is loaded via getServletConfigClasses method.

  2. Root WebApplicationContext where Spring Infra related configuration is loaded, such as SpringSecurityConfig, and it is loaded via getRootConfigClasses method.

Also according to the answer, and many more tutorials available online, it suggested to return SpringSecurityConfigClass via getRootConfigClasses method, i.e. doing below:

    @Override
    protected Class<?>[] getRootConfigClasses() {
        // TODO Auto-generated method stub
        return new Class[] {MySecurityConfig.class};
    }

But As I told I am not having to do the above to get MySpringSecurity config loaded into application context. So I believe the magic happens due to @EnableWebSecurity annotation. Is my understanding Correct? Then what is the need of returning SecurityConfig via getRootConfigClasses, is there any difference if we do not?

If I remove the @EnableWebSecurity annotation, but return the Configuration class via getRootConfigClasses like above, the application does not work. So @EnableWebSecurity is must.

I feel stupid for asking this but could not find any satisfactory answer on SO/Internet.

I was expecting that either it will be must to, return MySecuirityConfig class via getRootConfigClasses method, as we have to do for SpringServletConfig class.

  • 1
    The `@EnableWebSecurity` is for registering the additional configuration classes needed to setup security. WIthout this it will not work. However if the configuration class ins't loaded adding that annotation doesn't do anything. Loading can be done through either using `getRootConfigClasses` or by importing/detecting it. In your coase you have an `@ComponentScan` which detects the additional configuration class and registers it. An `@Configuration` is a specialized `@Component`. – M. Deinum Mar 23 '23 at 07:46

0 Answers0